Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Double Context Extension (Kotlin) #Retty_tech_cafe
Search
Taro Nagasawa
December 09, 2016
Programming
0
320
Double Context Extension (Kotlin) #Retty_tech_cafe
Retty Tech Cafe #8 (
https://retty.connpass.com/event/45628/)で発表した資料です
。
Taro Nagasawa
December 09, 2016
Tweet
Share
More Decks by Taro Nagasawa
See All by Taro Nagasawa
Android開発者のための Kotlin Multiplatform入門
ntaro
0
1.2k
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
2.3k
#Ubie 狂気の認知施策と選考設計
ntaro
13
14k
UbieにおけるサーバサイドKotlin活用事例
ntaro
1
1.2k
KotlinでSpring 完全理解ガイド #jsug
ntaro
6
3.6k
Kotlinでサーバサイドを始めよう!
ntaro
1
1k
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.9k
Kotlin Contracts #m3kt
ntaro
4
4.3k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
540
Other Decks in Programming
See All in Programming
LLM Observabilityによる 対話型音声AIアプリケーションの安定運用
gekko0114
2
430
humanlayerのブログから学ぶ、良いCLAUDE.mdの書き方
tsukamoto1783
0
200
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
120
CSC307 Lecture 09
javiergs
PRO
1
840
Grafana:建立系統全知視角的捷徑
blueswen
0
330
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.6k
Package Management Learnings from Homebrew
mikemcquaid
0
230
組織で育むオブザーバビリティ
ryota_hnk
0
180
CSC307 Lecture 10
javiergs
PRO
1
660
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
200
AgentCoreとHuman in the Loop
har1101
5
240
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
690
Featured
See All Featured
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
9.6k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
Raft: Consensus for Rubyists
vanstee
141
7.3k
Become a Pro
speakerdeck
PRO
31
5.8k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
410
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.7k
Testing 201, or: Great Expectations
jmmastey
46
8k
Typedesign – Prime Four
hannesfritz
42
2.9k
Optimising Largest Contentful Paint
csswizardry
37
3.6k
Transcript
Double Context Extension Retty Tech Cafe #8 2016-12-09 長澤 太郎
自己紹介 • 長澤 太郎 たろーって呼んでね ◦ @ngsw_taro • エンジニア@エムスリー株式会社 ◦
Android, Kotlin, Java, Spring, Railsなど • Kotlinエバンジェリスト • ディズニーが好き
Kotlinいいよね! • 型推論 • ラムダ式 • NULL安全 • Extension •
委譲プロパティ • 分解宣言 • コルーチン • 型エイリアス
Kotlinいいよね! • 型推論 • ラムダ式 • NULL安全 • Extension •
委譲プロパティ • 分解宣言 • コルーチン • 型エイリアス
Extension(拡張) • 拡張関数 • 拡張プロパティ fun String.hello() { println("Hello, $this")
} "world".hello() val String.initial: Char? get()=firstOrNull()?.toUpperCase() "world".initial
拡張関数じゃ物足りない問題
こんな関数呼び出しをしたい! class MyActivity: FragmentActivity { ... fun showMessage() { //
myDialog.show(supportFragmentManager, "tag") myDialog.show("tag") } }
こんな関数呼び出しをしたい! class MyActivity: FragmentActivity { ... fun showMessage() { //
myDialog.show(supportFragmentManager, "tag") myDialog.show("tag") } } DialogFragmentに拡張関数showを生やせば? いや、プロパティsupportFragmentManagerが必要だ... →FragmentManagerに依存
クラスの中に拡張関数を定義してみる class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) {
show(supportFragmentManager, tag) } fun showMessage() { myDialog.show("tag") } }
クラスの中に拡張関数を定義してみる class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) {
show(supportFragmentManager, tag) } fun showMessage() { myDialog.show("tag") } } イケる!?
再利用ができない問題... class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) {
show(supportFragmentManager, tag) } } class YourActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } }
再利用ができない問題... class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) {
show(supportFragmentManager, tag) } } class YourActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } } 同じコードが重複する
どうするか?
if (ちょっとした実験とか趣味のコード) { } else { }
if (ちょっとした実験とか趣味のコード) { recommend(DoubleContextExtension) } else { }
if (ちょっとした実験とか趣味のコード) { recommend(DoubleContextExtension) } else { recommend(Extension至上主義を捨てよ) }
Double Context Extension • 2つのコンテキストを持った拡張関数 • 命名 by 私 •
見た目: 型Aの定義中で、型Aに依存しながらも型Bの拡張関 数を生やすことができる class MyActivity: FragmentActivity { ... fun showMessage() { myDialog.show("tag") } }
Double Context Extension • 実際のコード: 「B型の拡張関数」を返す「A型の拡張プロパ ティ」を定義する // どこか適当なファイル val
FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) }
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag)
} class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... }
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag)
} class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... } FragmentActivityの 拡張関数showの呼び出し
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag)
} class MyActivity: FragmentActivity { fun showMessage() { myDialog.(this.show)("tag") } ... } こう書いても同じ
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag)
} class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... } 返って来た拡張関数オブジェクトを myDialogをレシーバに、 ”tag”を引数にして呼び出す
まとめ • 拡張関数って便利だよね • でも限界がある • Double Context Extensionという提案
まとめ • 拡張関数って便利だよね • でも限界がある • Double Context Extensionという提案 •
変なことしないで素直なコードを心がけましょう