Kotlin의 튜토리얼을 시도한 ⑤
htps : // try. 이 tぃんぁ g. rg/#/에ぁmpぇs/로 ぇ가 d%20p로페 치에 s/쿠s와 m%20으로 ぇ가//s와 m%20으로 ぇ가. kt
자신이 구현한 만큼의 리포지토리
htps : // 기주 b. 코 m / 아카츠키 174 / 코 t ぃ
위의 DelegatedProperties.kt 파일
Delegated properties
Custom delegate
import kotlin.reflect.KProperty
class Example {
var p: String by Delegate()
override fun toString() = "Example Class"
}
class Delegate() {
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
return "$thisRef, thank you for delegating '${prop.name}' to me!"
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
println("$value has been assigned to ${prop.name} in $thisRef")
}
}
fun main(args: Array<String>) {
val e = Example()
println(e.p) // getterが呼ばれる
e.p = "NEW" // setterが呼ばれる
}
프로퍼티의 뒤에 by
를 기술해 delegate 를 구현하고 있습니다. 속성의 delegates 는 interface 로 구현될 필요는 없습니다. 프로퍼티가 val
로 선언되고 있을 때는 getValue()
하지만, 프로퍼티이 var
로 선언되고 있을 때는 getValue()
에 가세해 setValue()
도 준비할 필요가 있습니다.
Lazy property
class LazySample {
val lazy: String by lazy {
println("computed!")
"my lazy"
}
}
fun main(args: Array<String>) {
val sample = LazySample()
// 1回目の呼び出し時にはクロージャ内の処理が行われるが
// 2回目以降の呼び出し時には単に初回の評価結果が返される
println("lazy = ${sample.lazy}") // クロージャ内のprintln()文も実行される
println("lazy = ${sample.lazy}") // 初回評価結果である"my lazy"しかprintされない
}
이름대로 지연 속성을 나타냅니다. 처음에 get로 불렸을 때는 lazy()가 건네받은 람다 식이 실행되어 결과를 보관 유지합니다. 그 이후에 get로 불렸을 때는 그 보관 유지하고 있던 결과를 돌려줍니다.
디폴트의 동작에서는 지연 프로퍼티의 평가는 동기되어 처리는 1 개의 thread, 참조는 모든 thread로부터 할 수 있는 상태가 됩니다. 초기화 대리자 동기화가 필요하지 않고 여러 스레드에서 동시에 실행할 수 있도록하려면 LazyThreadSafetyMode.PUBLICATION
를 lazy() 함수의 매개 변수로 전달합니다. 만약 초기화가 항상 싱글 thread로 행해지는 것을 알고 있으면, LazyThreadSafetyMode.NONE
모드를 사용할 수 있습니다.
참고까지 이 enum의 공식 의 기술을 붙여 둡니다.
Observable property
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("no name") {
d, old, new ->
println(d) // -> var Person.name: kotlin.String
println("$old - $new")
}
}
fun main(args: Array<String>) {
val user = User()
println("最初 = ${person.name}") // -> 最初 = no name
person.name = "Carl" // -> no name - Carl
println("代入後 = ${person.name}") // -> 代入後 = Carl
}
observable 함수는 두 개의 인수(초기값과 수정을 위한 값(블록 부분))을 취합니다. 핸들러는 이름에 값을 할당할 때마다 호출되며 세 개의 매개변수(할당된 값, 이전 값, 새 값)가 있습니다.
observable() 대신 vetoable() 을 사용하면 속성에 할당하기 전에 람다 식이 실행되어 할당을 수행할지 여부를 값으로 반환합니다. 이렇게 하면 할당을 거부할 수 있습니다.
class Person {
var age: Int by Delegates.vetoable(3) {
d, old, new ->
println("$old -> $new")
old < new // 新しい値の方が大きくなかったら拒否
}
}
val person = Person()
println("age: 最初 = ${person.age}") // -> age: 最初 = 3
person.age = 4 // -> 3 -> 4
println("age: 代入後 = ${person.age}") // -> age: 代入後 = 4
person.age = 2 // -> 4 -> 2
println("age: 代入拒否後 = ${person.age}") // -> age: 代入拒否後 = 4
NotNull property
import kotlin.properties.Delegates
class User {
var name: String by Delegates.notNull()
fun init(name: String) {
this.name = name
}
}
fun main(args: Array<String>) {
val user = User()
// user.name -> IllegalStateException
user.init("Carl")
println(user.name)
}
Kotlin에서는 초기화되지 않은 추상화되지 않은 속성을 가질 수 없습니다. null로 초기화할 수도 있지만 액세스할 때마다 확인해야 합니다. Kotlin에는 이것을 해결하는 delegate가 있으며 특정 속성에 쓰기 전에 읽기를 시도하면 예외가 발생합니다. 할당 후 예상대로 움직입니다.
Properties in map
class User(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
fun main(args: Array<String>) {
val user = User(mapOf(
"name" to "John Doe",
"age" to 25
))
println("name = ${user.name}, age = ${user.age}")
}
속성을 map에 저장하는 예입니다. Json을 퍼스하거나 다른 동적 일을 할 때 자주 사용됩니다. map에서 값을 꺼낼 때는 문자열의 키를 사용합니다.
물론, read-only의 map이 아닌 Mutable인 map으로 해 var를 사용하면 할당시에 map 변경을 가능하게 할 수 있습니다.
class Dog(val map: MutableMap<String, Any?>) {
var name: String by map
var age: Int by map
}
val dog = Dog(mutableMapOf(
"name" to "Pochi",
"age" to 2
))
println("name = ${dog.name}, age = ${dog.age}") // -> name = Pochi, age = 2
dog.name = "Taro"
dog.age = 3
println("name = ${dog.name}, age = ${dog.age}") // -> name = Taro, age = 3
감상
notNull이 수수하게 편리하게 보입니다.
Swift에서도 초기화되지 않은 비 추상적 속성을 가질 수 없으며 값을 처음부터 할당 할 필요가 없다면 Int는 0이고 String은 ""로 초기화하거나 선택적으로 쓰고 있습니다. 하지 않고, notNull을 명시할 수 있는 것이 좋다고 생각했습니다.
업데이트가 쉽습니다.
IntelliJ IDEA의 이야기가 됩니다만 여러가지 업데이트가 편합니다. Kotlin의 버전 업, 플러그인 업데이트의 연락은 화면 오른쪽 하단에 나오고, 그것을 탭하면 해줍니다. Xcode보다 상당히 편하다고 생각했습니다.
Reference
이 문제에 관하여(Kotlin의 튜토리얼을 시도한 ⑤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/akatsuki174/items/aa55658b40d2c4695288
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Custom delegate
import kotlin.reflect.KProperty
class Example {
var p: String by Delegate()
override fun toString() = "Example Class"
}
class Delegate() {
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
return "$thisRef, thank you for delegating '${prop.name}' to me!"
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
println("$value has been assigned to ${prop.name} in $thisRef")
}
}
fun main(args: Array<String>) {
val e = Example()
println(e.p) // getterが呼ばれる
e.p = "NEW" // setterが呼ばれる
}
프로퍼티의 뒤에
by
를 기술해 delegate 를 구현하고 있습니다. 속성의 delegates 는 interface 로 구현될 필요는 없습니다. 프로퍼티가 val
로 선언되고 있을 때는 getValue()
하지만, 프로퍼티이 var
로 선언되고 있을 때는 getValue()
에 가세해 setValue()
도 준비할 필요가 있습니다.Lazy property
class LazySample {
val lazy: String by lazy {
println("computed!")
"my lazy"
}
}
fun main(args: Array<String>) {
val sample = LazySample()
// 1回目の呼び出し時にはクロージャ内の処理が行われるが
// 2回目以降の呼び出し時には単に初回の評価結果が返される
println("lazy = ${sample.lazy}") // クロージャ内のprintln()文も実行される
println("lazy = ${sample.lazy}") // 初回評価結果である"my lazy"しかprintされない
}
이름대로 지연 속성을 나타냅니다. 처음에 get로 불렸을 때는 lazy()가 건네받은 람다 식이 실행되어 결과를 보관 유지합니다. 그 이후에 get로 불렸을 때는 그 보관 유지하고 있던 결과를 돌려줍니다.
디폴트의 동작에서는 지연 프로퍼티의 평가는 동기되어 처리는 1 개의 thread, 참조는 모든 thread로부터 할 수 있는 상태가 됩니다. 초기화 대리자 동기화가 필요하지 않고 여러 스레드에서 동시에 실행할 수 있도록하려면
LazyThreadSafetyMode.PUBLICATION
를 lazy() 함수의 매개 변수로 전달합니다. 만약 초기화가 항상 싱글 thread로 행해지는 것을 알고 있으면, LazyThreadSafetyMode.NONE
모드를 사용할 수 있습니다.참고까지 이 enum의 공식 의 기술을 붙여 둡니다.
Observable property
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("no name") {
d, old, new ->
println(d) // -> var Person.name: kotlin.String
println("$old - $new")
}
}
fun main(args: Array<String>) {
val user = User()
println("最初 = ${person.name}") // -> 最初 = no name
person.name = "Carl" // -> no name - Carl
println("代入後 = ${person.name}") // -> 代入後 = Carl
}
observable 함수는 두 개의 인수(초기값과 수정을 위한 값(블록 부분))을 취합니다. 핸들러는 이름에 값을 할당할 때마다 호출되며 세 개의 매개변수(할당된 값, 이전 값, 새 값)가 있습니다.
observable() 대신 vetoable() 을 사용하면 속성에 할당하기 전에 람다 식이 실행되어 할당을 수행할지 여부를 값으로 반환합니다. 이렇게 하면 할당을 거부할 수 있습니다.
class Person {
var age: Int by Delegates.vetoable(3) {
d, old, new ->
println("$old -> $new")
old < new // 新しい値の方が大きくなかったら拒否
}
}
val person = Person()
println("age: 最初 = ${person.age}") // -> age: 最初 = 3
person.age = 4 // -> 3 -> 4
println("age: 代入後 = ${person.age}") // -> age: 代入後 = 4
person.age = 2 // -> 4 -> 2
println("age: 代入拒否後 = ${person.age}") // -> age: 代入拒否後 = 4
NotNull property
import kotlin.properties.Delegates
class User {
var name: String by Delegates.notNull()
fun init(name: String) {
this.name = name
}
}
fun main(args: Array<String>) {
val user = User()
// user.name -> IllegalStateException
user.init("Carl")
println(user.name)
}
Kotlin에서는 초기화되지 않은 추상화되지 않은 속성을 가질 수 없습니다. null로 초기화할 수도 있지만 액세스할 때마다 확인해야 합니다. Kotlin에는 이것을 해결하는 delegate가 있으며 특정 속성에 쓰기 전에 읽기를 시도하면 예외가 발생합니다. 할당 후 예상대로 움직입니다.
Properties in map
class User(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
fun main(args: Array<String>) {
val user = User(mapOf(
"name" to "John Doe",
"age" to 25
))
println("name = ${user.name}, age = ${user.age}")
}
속성을 map에 저장하는 예입니다. Json을 퍼스하거나 다른 동적 일을 할 때 자주 사용됩니다. map에서 값을 꺼낼 때는 문자열의 키를 사용합니다.
물론, read-only의 map이 아닌 Mutable인 map으로 해 var를 사용하면 할당시에 map 변경을 가능하게 할 수 있습니다.
class Dog(val map: MutableMap<String, Any?>) {
var name: String by map
var age: Int by map
}
val dog = Dog(mutableMapOf(
"name" to "Pochi",
"age" to 2
))
println("name = ${dog.name}, age = ${dog.age}") // -> name = Pochi, age = 2
dog.name = "Taro"
dog.age = 3
println("name = ${dog.name}, age = ${dog.age}") // -> name = Taro, age = 3
감상
notNull이 수수하게 편리하게 보입니다.
Swift에서도 초기화되지 않은 비 추상적 속성을 가질 수 없으며 값을 처음부터 할당 할 필요가 없다면 Int는 0이고 String은 ""로 초기화하거나 선택적으로 쓰고 있습니다. 하지 않고, notNull을 명시할 수 있는 것이 좋다고 생각했습니다.
업데이트가 쉽습니다.
IntelliJ IDEA의 이야기가 됩니다만 여러가지 업데이트가 편합니다. Kotlin의 버전 업, 플러그인 업데이트의 연락은 화면 오른쪽 하단에 나오고, 그것을 탭하면 해줍니다. Xcode보다 상당히 편하다고 생각했습니다.
Reference
이 문제에 관하여(Kotlin의 튜토리얼을 시도한 ⑤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/akatsuki174/items/aa55658b40d2c4695288
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Kotlin의 튜토리얼을 시도한 ⑤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/akatsuki174/items/aa55658b40d2c4695288텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)