#### # 참고
- https://incheol-jung.gitbook.io/docs/study/kotlin-in-action/1
- https://incheol-jung.gitbook.io/docs/study/kotlin/basic
- https://simsi6.tistory.com/32
#### # Kotlin
- https://kotlinlang.org/docs/basic-types.html
- 코트린에서는, 어떤 변수라도 멤버 함수와 속성을 호출 할 수 있다는 점에서 모든 것은 객체로 볼 수 있다.
- 일부타입은 특수 표현 내부 표현을 가질 수 있다.
- 예를 들어 number,character, boolean 타입은 런타임에 원시 타입 값으로 표현될 수 있지만,
- 사용자에게는 일반 클래스 처럼 보일 수 있다.
-
#### # 컴파일 속도
- java보다 조금 빠르다.
- 일반적으로는 증분 빌드 시 성능이 좋다.
- Kotlin vs Java : Compilation Speeed
#### # 변수는 val or var
- val : 변경불가 : immutable
- var : 변경가능 : mutable
#### # BASIC Types
- [https://kotlinlang.org/docs/basic-types.html](```[https]https://kotlinlang.org/docs/basic-types.html```)
```js
val one = 1 // Int
val threeBillion = 3000000000 // Long
val oneLong = 1L // Long
val oneByte: Byte = 1
```
- 부동소주점 : Float, Double
- IEEE 754 표준에 따르면 부동 소수점 유형은 저장 할 수 있는 소수점 자리 수에 다라 다르다.
- Float는 IEEE 754 단일 정밀도를 반영하고, Double은 두배의 정밀도를 반영한다.
#### # 부동 소스점 종류
- 분수로 초기화 된 변수의 경우 컴파일러는 Double 유형으로 유추하게 된다.
- 값에 대해 부동 소수점 유형을 명시적으로 지정하면 접미사 f 또는 F를 추가하면 된다.
- 부동 소수점이 7자리 이상일 경우 자동으로 반올림처리 된다.
```js
val pi = 3.14 // Double
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float, actual value is 2.7182817
```
#### # Underscores in numeric literals
```js
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
```
#### # Representation
```js
val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false
```
#### # 세미콜론 제거
```js
fun main (args: Array b ) {
return a
} else {
return b
}
}
```
```js
fun maxOf(a: Int, b: Int): Int = if ( a > b ) a else b
fun maxOf(a: Int, b: Int) = if ( a > b ) a else b
```
#### # Nullsafe
- Non-null
```js
var a: String = "abc"
a = null // error
```
- Nullable(?)
```js
var b: String? = "abc"
b = null // ok
```js
- ‘?.’ operator (for nullable)
```js
var b: String? = "abc"
b.length // error
b?.length // ok
```
- 여러 체인의 객체를 호출할 때 유용하다.
```js
// Java
String name;
if (bob != null) {
if (department != null) {
if (head != null) {
name = bob.department.head.name;
}
}
}
// Kotlin
var name: String = bob?.department?.head?.name ?: "" // ok
```
- !! operator (for nullable)
```js
for NPE-lovers.
var b: String? = null
val l = b!!.length // ok, but throw an NPE if b is null
```
- Safe casts
```js
val aInt: Int? = a as? Int // return `null` if the attempt was not successful
Collections of Nullable Type
val nullableList: List = listOf(1, 2, null, 4)
val intList: List = nullableList.filterNotNull()
```
#### # 접근자
- public (default) : 전역 프로젝트에 공개
- private : 같은 파일내에 공개
- protected : Subclasses에 공개
- internal : 같은 Module내에 공개
- Module이란?
- IntelliJ an IntelliJ IDEA module
- a Maven project
- a Gradle source set
- a set of files compiled with one invocation of the Ant task.
#### # 자동 형변환 (Smart Casts)
- is 체크 후 (Java의 instanceof)
```js
fun demo(x: Any) {
if (x is String) {
print(x.length) // x가 자동으로 String으로 형변환 된다.
}
}
```
- null 체크 후
```js
fun demo1(x: String?) {
if (x != null) {
demo2(x) // x가 자동으로 NonNull String으로 형변환 된다.
}
}
fun demo2(x: String) {
print(x.length)
}
```
#### # For-Loop
- List
```js
val items = listOf("apple", "banana", "kiwi")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
결과
item at 0 is apple
item at 1 is banana
item at 2 is kiwi
```
- Range (a…b)
```js
for (i in 0..10) {
print(i)
}
결과
012345678910
```
#### # While-Loop
```js
val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
결과
item at 0 is apple
item at 1 is banana
item at 2 is kiwi
```
#### # When
- 다양한 타입 비교
```js
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
```
- {} 블록을 지정해서 작성
```js
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
```
- 한 조건에 여러 값을 비교 (0, 1)
```
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
```
- 범위 비교
```js
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
```
#### # infix notation(중위 표기법)
- 함수앞에 infix를 붙인다.
- 멤버함수 혹은 확장 함수(extension funtions)에 사용
- 하나의 파라미터를 받는 함수에서 사용
```js
// 정의 방법
infix fun Int.shl(x: Int): Int {
...
}
```
#### # Extensions
```js
// ViewExt.kt
fun View.show() {
visibility = View.VISIBLE
}
fun View.hide() {
visibility = View.GONE
}
// SearchActivity.kt
var textView = findViewById(R.id.textView) as TextView
textView.show() // ok
textView.hide() // ok
```
#### # 클래스
- 기본
```js
class Invoice {
}
```
- 바디가 없을 때 {} 생략 가능
```js
class Empty
```
- 생성자 표현 ( constructor 키워드 )
```js
class Person constructor(firstName: String) {
}
```
- 생성자 표현에 constructor 키워드 생략 가능
```js
class Person(firstName: String) {
}
```
- 생성자의 초기화 블록 지정 (init 키워드)
```js
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
```
- 위 표현을 아래와 같이 표현 가능 (동일)
```js
class Customer {
constructor(name: String) {
logger.info("Customer initialized with value ${name}")
}
}
```
- @Inject 어노테이션이 필요하면 constructor 키워드가 필요하다.
```js
class Customer public @Inject constructor(name: String) { ... }
```
- Data 클래스
- 모든 var, val 변수의 Getter 제공
- 모든 var 변수의 Setter를 제공
- equals() / hashCode() / toString() / copy() 구현을 아름답게 제공
```js
data class Customer(val name: String, var email: String)
```
- Open 클래스
- 코틀린의 모든 클래스는 기본적으로 final이라 상속이 불가능하다.
- open 키워드를 class 앞에 붙여줌으로써 상속을 허용시킨다.
```js
open class Base(p: Int)
class Derived(p: Int) : Base(p)
```
- Abstract 클래스 (open 붙일 필요 없음)
```js
abstract class Base {
abstract fun f()
}
class Derived() : Base() {
override fun f() {
// ...
}
}
```
- Nested 클래스
- Outer클래스 멤버 참조가 불가능
```js
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2 // bar 참조 불가
}
}
val demo = Outer.Nested().foo() // == 2
```
- Inner 클래스
- Outer클래스 멤버 참조 가능
```js
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar // bar 참조 가능
}
}
val demo = Outer().Inner().foo() // == 1
```
- 익명 Inner 클래스
- object키워드를 사용하고 타입은 interface나 abstract class를 받는다.
- interface : 이름 뒤에 ()를 붙이지 않는다. View.OnClickListener
- abstract class : 이름 뒤에 ()를 붙인다. SimpleOnQueryTextListener()
```js
// interface
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View) {
// ...
}
})
// abstract class
searchView.setOnQueryTextListener(object : SimpleOnQueryTextListener() {
override fun onQueryTextSubmit(query: String): Boolean {
presenter.searchImage(query)
return false
}
})
```
#### # Enum 클래스
```js
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}
```
#### # 클래스 위임 (Class Delegation)
- 해당 클래스안에 by절 뒤에 오는 참조가 private으로 저장된다.
- 해당 클래스안에 by절 앞에 오는 인터페이스의 메소드를 자동 생성한다.
```js
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
// b가 Derived내에 private으로 저장 됨
// Base의 메소드를 Derived내에 자동 생성한다.
// 그 메소드들은 b를 참조하여 실행한다.
class Derived(b: Base) : Base by b
fun main(args: Array) {
val b = BaseImpl(10)
Derived(b).print() // prints 10
}
```
#### # Destructuring Declarations
```js
// class
data class Person(val name: String, val age: Int)
val (name, age) = Person("Jee-ryong", 30)
print("My name is $name and I am $age years old.")
// map
for ((key, value) in map) {
print("key is $key")
print("value is $value")
}
```
#### # List
- mutableListOf, arrayListOf 둘 다 ArrayList를 만들어 리턴
- ArrayList보다 kotlin스타일로 리스트를 다루는 인터페이스가 구현되어 있는 MutableList를 사용하는 편이 더 나아보임.
```js
val lists: List = listOf(1, 2, 3) // read only
val lists: MutableList = mutableListOf(1, 2, 3) // read/write
val lists: ArrayList = arrayListOf(1, 2, 3) // read/write
```
#### # Map
```js
// new instance
val map = mapOf("Korea" to 1, "Japan" to 2) // read only
val map = mutableMapOf("Korea" to 1, "Japan" to 2) // read/write
val map = linkedMapOf("Korea" to 1, "Japan" to 2)
val map = hashMapOf("Korea" to 1, "Japan" to 2)
val map = sortedMapOf("Korea" to 1, "Japan" to 2)
// use
map.put("London", 3)
map.get("Korea")
map["Korea"]
map.containsKey("Japan")
map.toList()
map.toMap()
map.toMutableMap()
map.toSortedMap()
```
#### # Set
```js
// new instance
val set = setOf("Korea", "Japan")
val set = mutableSetOf("Korea", "Japan")
val set = hashSetOf("Korea", "Japan")
val set = linkedSetOf("Korea", "Japan")
val set = sortedSetOf("Korea", "Japan")
// use
set.add("London")
set.remove("London")
set.contains("London")
set.size
set.toList()
set.toMutableList()
set.toSet()
set.toHashSet()
set.toMutableSet()
set.toSortedSet()
```
#### # Ranges
```js
for (i in 1..4) print(i) // prints "1234"
for (i in 1..4 step 2) print(i) // prints "13"
for (i in 4 downTo 1) print(i) // prints "4321"
for (i in 4 downTo 1 step 2) print(i) // prints "42"
for (i in 1 until 10) println(i) // prints "123456789"
(1..12 step 2).last // 11
```
#### # Equality
```js
Referential equality (===, !==)
val a = Integer(10)
val b = a
a === b // true
a !== b // false
val a = Integer(10)
val b = Integer(10)
a === b // false
a !== b // true
```
#### # Structural equality (==, !=)
```js
data class Person(val name: String, val age: Int)
val person = Person("Jae-ryong", 20)
val person2 = Person("Jae-ryong", 20)
person == person2 // true
person != person2 // false
```
#### # Arrays Equality (using infix funtions)
- contentEquals
```js
val hobbies = arrayOf("Hiking", "Chess")
val hobbies2 = arrayOf("Hiking", "Chess")
assertTrue(hobbies contentEquals hobbies2) // passed
// 참고 - contentEquals는 미리 정의 된 infix함수이다.
public infix inline fun kotlin.Array.contentEquals(other: kotlin.Array): kotlin.Boolean
```
#### # Lambdas
```js
// example
fun List.map(transform: (T) -> R): List {
val result = arrayListOf()
for (item in this)
result.add(transform(item))
return result
}
```
- input 파라미터 네이밍은 자유
```js
var ints = listOf(1,2,3,4,5)
val doubled = ints.map { value -> value * 2 }
```
- it을 사용하면 input 파라미터 생략가능
```js
ints.map { it * 2 }
```
- 사용하지 않는 파라미터는 _로 선언 가능
```js
var map = mapOf("Korea" to "Seoul", "Japan" to "Tokyo")
map.forEach { _, value -> println("$value!") }
```
'mobile' 카테고리의 다른 글
Android / IOS 단말 해상도 (0) | 2019.07.18 |
---|---|
안드로이드 잡인텐트서비스 : Android Jobintentservice (0) | 2019.07.16 |
폰갭(PhoneGap) - 코르도바(cordova) (0) | 2019.07.15 |
폰갭(PhoneGap) - 코르도바(cordova) (0) | 2019.01.30 |
[안드로이드] URL SCHEME (0) | 2014.05.21 |
댓글