Kotlin 속성 에이전트를 사용하여 코드를 아름답게 만들기

14842 단어 kotlin
내 동료와 나는 이틀간의 Kotlin 교육 다음날 고급 Kotlin 주제를 준비할 것이다.우리는 지금 우리 회사iteratec의 Kotlin 트레이너입니다. 이것은 정말 놀랍습니다. 저는 앞으로 몇 주 동안 어떻게 실현되었는지 다른 블로그를 쓸 것입니다.겸사겸사 한마디: 고급 Kotlin 교육에서 무엇을 배우고 싶으시면: 아래에 메시지를 남기거나 저에게 편지를 쓰세요!📩
이번 교육의 주제를 선택하기 위해 우리는 많은 Kotlin 기능과 라이브러리를 토론했다.그중 하나는 의뢰 속성이다.그는 들은 적이 있지만 아직 사용하지 않았다.그래서 나는 곧 IntelliJ를 열어 그에게 이 예를 보여 주었다.

부동산 매듭


이것은 상당히 표준적이다. Kotlin에서 우리는 var 로 가변 속성을 정의하고 val 로 값을 정의할 수 있다.코드를 살펴보겠습니다.
class Preferences {
    var username : String = ""
}
여기에는 속성이 하나 있습니다username.모든 가변 속성은 getter와setter가 있습니다. 덮어쓸 수 있습니다.참고로 메모리의 구문을 모르면 Alt + Enterusername 를 간단히 입력하고 빠른 작업을 할 수 있습니다.

Kotlin docs on properties 이 방면에 관한 내용이 더 많다.단, 의뢰 속성을 만들 수 있습니다. 그 중에서 getter와setter는 다른 곳에서 제공합니다.

의뢰 속성이 있는 좋은 코드

by 키워드와 의뢰 실례를 사용하여 의뢰 속성을 간단하게 정의할 수 있습니다. 예를 들어 described in the Kotlin docs:
class Preferences {
    var username : String by Delegate()
}
이것은 연산자 함수getValuesetValue를 실현하는 모든 종류가 될 수 있다.이러한 컨텐트는 문서에서 복사할 수 있지만 IntelliJ에서 클래스를 생성하기만 하면 됩니다.문법을 이해하는 데 도움을 줄 수 있는 인터페이스ReadWritePropertyReadOnlyProperty도 있습니다.
예를 들어, 파일에서 텍스트를 읽고 쓰는 데 사용되는 FileDelegate 를 만들고 파일 이름을 매개 변수로 사용합니다.
class Preferences {
    var username: String by FileDelegate("username.txt")
}

class FileDelegate(val fileName: String) : ReadWriteProperty<Preferences, String> {

    override fun getValue(thisRef: Preferences, property: KProperty<*>): String {
        val file = File(fileName)
        return if (file.exists()) file.readText() else ""
    }

    override fun setValue(thisRef: Preferences, property: KProperty<*>, value: String) {
        File(fileName).writeText(value)
    }

}
이제 우리는 액세스 속성을 통해 파일username.txt의 내용에 접근할 수 있습니다!이거 멋있지 않아요?
fun main() {
    val preferences = Preferences()
    println(preferences.username)
    preferences.username = "Marc"
    println(preferences.username)
}
더 좋은 것은 우리가 현재 여러 속성에 대해 같은 기능을 다시 사용할 수 있다는 것이다.
class Preferences {
    var username: String by FileDelegate("username.txt")
    var accessToken: String by FileDelegate("accessToken.txt")
    var favoriteFood: String by FileDelegate("favoriteFood.txt")
}
만약 우리가 심지어 속성의 이름에 따라 파일 이름을 생성할 수 있다면, 그것은 좋지 않습니까?간단합니다. 각각KProperty마다 하나property.name가 있기 때문에 우리는 사용할 수 있습니다.
class FileDelegate : ReadWriteProperty<Preferences, String> {

    override fun getValue(thisRef: Preferences, property: KProperty<*>): String {
        val file = File(property.name + ".txt")
        return if (file.exists()) file.readText() else ""
    }

    override fun setValue(thisRef: Preferences, property: KProperty<*>, value: String) {
        File(property.name + ".txt").writeText(value)
    }

}
비록 작은 변동일 뿐이지만, 이것은 코드를 더욱 읽을 수 있게 한다.물론 대가가 있다. 만약 누군가가 속성 이름을 재구성한다면 파일 이름도 바뀔 것이다.만약 우리가 이 점을 받아들이기를 원한다면, 코드는 다음과 같다.
class Preferences {
    var username: String by FileDelegate()
    var accessToken: String by FileDelegate()
    var favoriteFood: String by FileDelegate()
}
또한 ReadWriteProperty<Preferences, String> 에서 확장되었기 때문에 유형 추정 자동 획득 String 유형 반환:
class Preferences {
    var username by FileDelegate()
    var accessToken by FileDelegate()
    var favoriteFood by FileDelegate()
}
가령 favoriteFood.txt 이 다른 프로그램에서 생성되었다면, 우리는 단지 여기서 그것을 읽고 싶을 뿐이다.우리는 varval 로 변경할 수 있습니다. 이것은 실제로 setter를 숨깁니다.
   val favoriteFood by FileDelegate()
이것은 매우 편리하다고 생각합니다. 의뢰 속성은 당신의 Kotlin 항목을 더욱 쉽게 읽을 수 있습니다.의뢰 속성을 다음과 같이 사용할 수 있습니다.
  • 디스크에서 읽기/쓰기
  • 캐시 값(매번 다시 읽는 것이 아니라)
  • Android의 읽기 및 쓰기 공유 기본 설정 (참조 this great blog post
  • 네트워크에서 정보를 얻습니다(협동 루트를 사용한다면 반드시 호출해야 합니다runBlocking. 왜냐하면 이런 메커니즘은 현재 협동 루트를 끊는 것을 지원하지 않기 때문입니다. - 적어도 저는 모릅니다.)
  • 로깅 수행
  • 잠깐만, 더 있어!


    Kotlin documentation on delegated properties 더 많은 지식을 포함한다.예를 들어 나는 Kotlin의 stdlib lazy 의뢰를 알고 있다. 이것은 비싼 조작의 결과를 얻고 저장하는 데 사용할 수 있다.
    val lazyValue: Int by lazy {
        calculateAnswer() // takes 7.5 million years to print 42
    }
    
    제가 모르는 것은 스레드 보안 모드를 정의할 수 있다는 것입니다. (기본적으로 lazy는 동기화되어 있기 때문에 예상보다 더 많은 비용이 증가할 수 있습니다.)
    val lazyValue: Int by lazy(mode = LazyThreadSafetyMode.NONE) {
        calculateAnswer() // takes 7.5 million years to print 42
    }
    
    Kotlin 문서에서 설명한 변경할 수 없는 매핑과 같이 매핑을 의뢰할 수 있습니다.
    class User(val map: Map<String, Any?>) {
        val name: String by map
        val age: Int     by map
    }
    
    좋은 Kotlin 있으세요!🎉
    만약 당신이 이 게시물을 좋아한다면, 그것을 하나 주십시오❤️, 아래+FOLLOW 버튼을 누르면 따라와!이것은 내가 동력을 유지하고 더 많은 이 직위를 창조하는 데 도움을 줄 것이다.😊
    표지 사진은 Anton Sulsky 에서 촬영되었다.

    좋은 웹페이지 즐겨찾기