by lazy:遅延初期化を深く学ぶ
SYNCHRONIZED、PUBLICATION、NONEの遅延初期化モードを学びます。
「by lazy:遅延初期化を深く学ぶ」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
by lazyとは
by lazyは、valの初期化を最初にアクセスするまで遅延させます。ラムダは一度だけ実行され、結果がキャッシュされます。
val greeting: String by lazy {
println("Computing...")
"Hello, Kotlin!"
}
fun main() {
println(greeting) // prints Computing... then Hello, Kotlin!
println(greeting) // prints Hello, Kotlin! (cached)
}Lazyの構文
by lazyデリゲートは、プロパティ宣言から推論された型の値を返すラムダを受け取ります。
val pi: Double by lazy { Math.PI }
val appName: String by lazy { "MyApp v1.0" }
fun main() {
println(pi) // 3.141592653589793
println(appName) // MyApp v1.0
}SYNCHRONIZEDモード(デフォルト)
デフォルトでは、lazyはLazyThreadSafetyMode.SYNCHRONIZEDを使用し、1つのスレッドだけが値を初期化します。
val heavyResource: String by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
Thread.sleep(100) // simulate work
"Resource ready"
}
fun main() { println(heavyResource) }PUBLICATIONモード
PUBLICATIONでは複数のスレッドが同時に初期化できます。最初の結果が採用されます。初期化が軽量で副作用がない場合に使用してください。
val config: Map<String, String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
mapOf("host" to "localhost", "port" to "8080")
}
fun main() { println(config["host"]) }NONEモード
NONEには同期のオーバーヘッドがありません。パフォーマンスが重要な単一スレッド環境でのみ使用してください。
val singleThreadValue: Int by lazy(LazyThreadSafetyMode.NONE) {
42
}
fun main() { println(singleThreadValue) }クラス内でのLazy
クラス内のby lazyは、プロパティに最初にアクセスしたときに初期化されます。インスタンスの状態に依存する高コストな計算に便利です。
class DatabaseConnection(val url: String) {
val pool: String by lazy {
println("Connecting to $url")
"Pool@$url"
}
}
fun main() {
val db = DatabaseConnection("localhost:5432")
println(db.pool)
}Lazyとlateinitの比較
複雑な初期化を行うvalにはby lazyを使用します。外部(テストや依存性注入など)から代入するvarにはlateinitを使用します。
class MyService {
val computed: List<Int> by lazy { (1..100).toList() }
lateinit var injected: String
}
fun main() {
val s = MyService()
s.injected = "injected value"
println(s.computed.size)
println(s.injected)
}isInitializedチェック
プロパティが初期化済みかどうかは.isInitialized()で確認できます。ただし、デリゲート参照経由でのみ使用できます。
val myLazy: String by lazy { "initialized" }
fun main() {
val ref = ::myLazy
// No direct isInitialized on val lazy, but we can check via delegate
println(myLazy)
}依存関係のあるLazy
Lazyプロパティは他のLazyプロパティを参照できるため、遅延初期化のチェーンを構築できます。
val baseUrl: String by lazy { "https://api.example.com" }
val usersUrl: String by lazy { "$baseUrl/users" }
val postsUrl: String by lazy { "$baseUrl/posts" }
fun main() {
println(usersUrl)
println(postsUrl)
}実践:Singleton Service
object宣言でby lazyを使用すると、負荷の大きいシングルトンを必要なときに初期化できます。
object Analytics {
val client: String by lazy {
println("Initializing analytics client")
"AnalyticsClient@ready"
}
}
fun main() {
println("App started")
println(Analytics.client) // initialized on first use
println(Analytics.client) // cached
}正規表現の遅延コンパイル
正規表現のコンパイルにはコストがかかります。by lazyを使用して一度だけコンパイルして再利用し、繰り返し発生するオーバーヘッドを避けてください。
val emailRegex: Regex by lazy {
Regex("^[A-Za-z0-9+_.-]+@(.+)$")
}
fun isValidEmail(email: String) = emailRegex.matches(email)
fun main() {
println(isValidEmail("user@example.com")) // true
println(isValidEmail("bad-email")) // false
}クイックチェック
最大のパフォーマンスが必要な単一スレッド環境では、どのlazyモードを使用すべきですか?
振り返り
by lazyは最初のアクセス時にラムダを一度だけ実行し、結果をキャッシュします。スレッドセーフ性にはSYNCHRONIZED(デフォルト)、同時実行可能なべき等の初期化にはPUBLICATION、単一スレッドでのパフォーマンスにはNONEを選択してください。
よくある質問
「by lazy:遅延初期化を深く学ぶ」レッスンは無料ですか?
はい。「by lazy:遅延初期化を深く学ぶ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「by lazy:遅延初期化を深く学ぶ」で何を学びますか?
SYNCHRONIZED、PUBLICATION、NONEの遅延初期化モードを学びます。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「by lazy:遅延初期化を深く学ぶ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- by lazy:遅延初期化を深く学ぶ
- observableとvetoableデリゲート
- カスタムReadWritePropertyデリゲートの作成
- Preferences、Map委譲プロパティ、ロギングのデリゲート