Kotlin - Sizuha/devdog GitHub Wiki
Google์์ Android ๊ฐ๋ฐ์ธ์ด๋ก ๊ณต์ ์ง์ ๊ฒฐ์ .
Android Studio 3.0 ๋ถํฐ ์ง์.
- ๊ณต์ ์ฌ์ดํธ https://kotlinlang.org/docs/reference/android-overview.html
// Java
String s = "abc";
final String t = "xyz";
// Kotlin
var s: String = "abc"
val t: String = "xyz"
var s = "abc"
val t = "xyz"
Type | Bit width |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
Decimals: 123
Long: 123L
Hexadecimals: 0x0F
Binaries: 0b00001011
Doubles: 123.5, 123.5e10
Floats: 123.5f
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
Char
Character literals go in single quotes: '1'.
Special characters can be escaped using a backslash.
The following escape sequences are supported: \t, \b, \n, \r, ', ", \ and $.
To encode any other character, use the Unicode escape sequence syntax: '\uFF00'.
var b: Boolean = true
b = false
// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
val s: String = "Hello, world!\n"
A raw string is delimited by a triple quote ("""), contains no escaping and can contain newlines and any other characters:
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
fun main(args: Array<String>) {
println("---")
println("""
|for (i = 0; i < 100; ++i)
|console.log(i)
""".trimMargin())
println("---")
println("""
> a
> b
> c
> d
""".trimMargin("> "))
println("---")
}
๊ฒฐ๊ณผ
---
for (i = 0; i < 100; ++i)
console.log(i)
---
a
b
c
d
---
fun main(args: Array<String>) {
println("---")
println("""
for (i = 0; i < 100; ++i)
console.log(i)
""".trimIndent())
println("---")
}
๊ฒฐ๊ณผ
---
for (i = 0; i < 100; ++i)
console.log(i)
---
val i = 10
val s = "i = $i" // evaluates to "i = 10"
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
Templates are supported both inside raw strings and inside escaped strings. If you need to represent a literal $ character in a raw string (which doesn't support backslash escaping), you can use the following syntax:
val price = """
${'$'}9.99
"""
import foo.Bar // Bar is now accessible without qualification
import foo.* // everything in 'foo' becomes accessible
import bar.Bar as bBar // bBar stands for 'bar.Bar'
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
}
else {
max = b
}
// As expression
val max = if (a > b) a else b
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
when replaces the switch operator of C-like languages. In the simplest form it looks like this
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
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")
}
// As expression (1)
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
// As expression (2)
val groupCode = when(number) {
0 -> 0
in 1..10 -> 1
in 11..100 -> 2
else -> 3
}
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
for (item: Type in Collection) {
// ...
}
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
ไพ๏ผ 1 ~ 100 ๊น์ง ๋ฃจํ
// ๊ธฐ๋ณธ์ ์ผ๋ก range ํํ์ ์ด์ฉํ๋ค.
// 1.
for (i in 1..100) { ... }
// 2.
(1..100).forEach { i -> }
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y is visible here!
return, break, continue
loop@ for (i in 1..100) {
for (j in 1..100) {
if (...) break@loop
}
}
fun foo() {
ints.forEach lit@ {
if (it == 0) return@lit
print(it)
}
}
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
Expression | Translated to |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a++ | a.inc() |
a-- | a.dec() |
Expression | Translated to |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a..b | a.rangeTo(b) |
a in b | b.contains(a) |
a !in b | !b.contains(a) |
Expression | Translated to |
---|---|
a[i] | a.get(i) |
a[i, j] | a.get(i, j) |
a[i] = b | a.set(i, b) |
a[i, j] = b | a.set(i, j, b) |
Expression | Translated to |
---|---|
a() | a.invoke() |
a(i) | a.invoke(i) |
Expression | Translated to |
---|---|
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
Expression | Translated to |
---|---|
a == b | a?.equals(b) ?: (b === null) |
a != b | !(a?.equals(b) ?: (b === null)) |
Expression | Translated to |
---|---|
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
https://kotlinlang.org/docs/reference/ranges.html
1์์ 100๊น์ง (100 ํฌํจ)
for (i in 1..100) {
print(i)
}
1์์ 99๊น์ง(100 ๋ฏธํฌํจ)
for (i in 1 until 100) {
print(i)
}
100์์ 1๋ก (1 ํฌํจ)
for (i in 100 downTo 1) {
print(i)
}
0๋ถํฐ 100๊น์ง, ๋จ 2์ฉ ์ฆ๊ฐ
for (i in 0..100 step 2) {
print(i)
}
100์์ 0๊น์ง, ๋จ 2์ฉ ๊ฐ์
for (i in 100 downTo 0 step 2) {
print(i)
}
class Some {
}
class Person constructor(firstName: String) {
}
//--- or ---//
class Person(firstName: String) {
}
class AClass(some: String) {
lateinit var field: String
init {
field = some
}
}
//--- or ---//
class AClass(some: String) {
val field: String = some
}
//--- or ---//
class AClass(val field: String) {
}
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
init ๋ธ๋ก์ constructor ๋ธ๋ก ์ ์ ๋ณด๋ค๋ ๋จผ์ ์ํ๋จ.
class Customer(val customerName: String = "") {}
val customer = Customer("Joe Smith")
class AClass {
var name: String
get() = this.toString()
set(value) { name = value }
}
์ฝ๊ธฐ์ ์ฉ์ผ๋ก ๋ง๋ค๊ธฐ
class AClass {
var name: String
get() = this.toString()
private set
}
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
Inner Class๋ ์์ ์ด ์ ์ธ๋ ํด๋์ค ์์ญ์ ๋งด๋ฒ์ ๋ฐ๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
window.addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
Kotlin์ ๊ธฐ๋ณธ์ ์ผ๋ก final class์ด๋ค. open class๋ก ์ ์ธํด ์ค์ผ ์์ ๊ฐ๋ฅ. ๋งค์๋๋ ๋ง์ฐฌ๊ฐ์ง.
Java์ฒ๋ผ interface ํค์๋๋ก ์ ์.
// ์ ์
interface ISome {
var fieldA: String // ํ๋กํผํฐ
val fieldB: String // ํ๋กํผํฐ
fun testA()
fun testB(): Boolean { return true } // ๊ธฐ๋ณธ ๋์์ ์ง์ ํ ์ ์๋ค
}
// ์ฌ์ฉ
class SomeClass : ISome {
override var fieldA
get() = "TEST"
private set
override val fieldB = "TEST2"
override fun testA { /* ... */ }
}
fun <T> someFunc() { ... }
// T์ ๋ํ ํ์
์กฐ๊ฑด์ ์ถ๊ฐ
fun <T: SomeType> someFunc() { ... }
// T์ ๋ํ ์ฌ๋ฌ๊ฐ์ ํ์
์กฐ๊ฑด์ ์ถ๊ฐ
fun <T> someFunc()
where T: SomeTypeA, T: SomeTypeB
{ ... }
// ๋ฌผ๋ก ์ ๋ค๋ฆญ ํ์
์ ์ฌ๋ฌ๊ฐ ์ง์ ํ ์๋ ์๋ค
fun <E, R> someFunc() { ... }
class ํน์ interface ๋ฑ์ ์ ๋ค๋ฆญ์ ์ง์ ํ ์ ์๋ค.
class SomeClass<T> {
// . . .
}
๋ง์ฐฌ๊ฐ์ง๋ก ํ์ ์ ํ์ ๊ฑธ ์๋ ์๋ค.
class SomeClass<T: SomeType> {
// . . .
}
class SomeClass<T>
where T: SomeTypeA, T: SomeTypeB {
// . . .
}
์ ๋ค๋ฆญ ํ์ ์ out ํค์๋๋ก ์ ์ธํ๋ฉด ๋ฆฌํด ํ์ ์ผ๋ก๋ง ์ฌ์ฉ์ด ์ ํ๋๋ค.
interface ISome<out T> {
fun someFunc(): T
}
๋ฐ๋๋ก in ํค์๋๋ก ์ ์ธ๋ ํ์ ์ ์ธ์๋ก์๋ง ์ฌ์ฉ๋๋ค.
interface ISome<in T> {
fun someFunc(a: T)
}
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
annotation class Column(
val name: String,
val notNull: Boolean = false,
val unique: Boolean = false,
val exclude: Boolean = false
)
annotation class ํค์๋๋ก ์ด๋
ธํ
์ด์
ํด๋์ค๋ฅผ ์์ฑํ๋ค.
์ด๋
ธํ
์ด์
์์ ์ทจ๊ธํ๋ ์ธ์์ ํ์
์ ๊ธฐ๋ณธ ํ์
๋ง ์ง์ ํ ์ ์๋ค.
@Target() ์ด๋ ธํ ์ด์ ์ผ๋ก ํด๋น ์ด๋ ธํ ์ด์ ์ด ์ด๋์ ๋ถ์ ์ ์๋์ง ์ ํ์ ๋๋ค.
Android ํ๋ก์ ํธ์์, build.gradle (Module) ์ค์
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
ํ์ ๋ช ::class.memberProperties๋ ๋งด๋ฒ ๋ณ์, ํ๋กํผํฐ๋ฅผ ํ์ํ ์ ์๋ค.
for (member in some::class.memberProperties) {
// ์ด๋
ธํ
์ด์
ํ์(1)
member.annotations.forEach { a: Annotation ->
// ...
}
// ์ด๋
ธํ
์ด์
ํ์(2)
member.findAnnotation<AnnotationType>()?.let { /* ... */ }
}
ํด๋์ค ๋งด๋ฒ์ ๋ฆฌํด ํ์ ์ ํ์ธ.
for (member in some::class.memberProperties) {
when (member.returnType) {
Int::class.createType() -> { /* ... */ }
else -> { /* ... */ }
}
}
**ํ์ ๋ช ::class.createType()**์ผ๋ก ๋น๊ตํ๋ ๊ฒ์ ์ฃผ์.
// member: KMutableProperty<*>
// ์ฝ๊ธฐ
val r = member.getter.call(...)
// ์ฐ๊ธฐ
member.setter.call(...)
val accessible = member.isAccessible
member.isAccessible = true
member.setter.call(tableObj, value)
member.isAccessible = accessible
๋ค์๊ณผ ๊ฐ์ด class๋ฅผ ์ ์ํ๋ค๊ณ ํ ๋,
class NameCard {
var name = ""
var tel = ""
var email = ""
}
apply์ ๊ฒฝ์ฐ
val newCard: NameCard = NameCard().apply { // this = NameCard()
name = "xxxxxx"
tel = "000-0000-0000"
email = "[email protected]"
// ์๋์ผ๋ก this๋ฅผ ๋๊ฒจ์ค
}
also์ ๊ฒฝ์ฐ
val newCard: NameCard = NameCard().also { // it = NameCard()
it.name = "xxxxxx"
it.tel = "000-0000-0000"
it.email = "[email protected]"
// ์๋์ผ๋ก it์ ๋๊ฒจ์ค
}
run์ ๊ฒฝ์ฐ
val newCard: NameCard()
newCard.run { // this = newCard
name = "xxxxxx"
tel = "000-0000-0000"
email = "[email protected]"
}
let์ ๊ฒฝ์ฐ
val newCard: NameCard()
newCard.let { // it = newCard
it.name = "xxxxxx"
it.tel = "000-0000-0000"
it.email = "[email protected]"
}