ãã€ãŠãAndrei abreslav Breslavã¯ãKotlinã¯äŸ¿å©ã§äºæž¬å¯èœãªèšèªãšããŠéçºããããšè¿°ã¹ãŸããã åæã«ããã®èšèªã§ã¯å°æè ïŒçãã³ãŒããçµæã¯äºæ³å€ãæãããããŸãã¯å€±æããïŒã¯èŠã€ãããªããšã®æèŠããããŸããã Anton antonkeks Keksã¯IDEAã§å¬åãããŸã äœããæãèµ·ãããŸããããããŠãå®äŸã§ããã圌ã¯Philip KeksãšååããŠåœŒã®çºèŠã«ã€ããŠè©±ããŸããã èªåã§èŠãŠãã ããïŒ
ã«ããã®äž-ãã®ãããªããºã«ã®éžæãšãããã«é¢ãã詳现ãªã³ã¡ã³ãã ãã®è³æã¯ã Mobius 2017ã«ã³ãã¡ã¬ã³ã¹ïŒãµã³ã¯ãããã«ãã«ã¯ïŒã§ã® Anton KeksïŒCodeborneïŒãšPhilip KeksïŒCreative mobileïŒã®ã¬ããŒãã«åºã¥ããŠããŸãã
Kotlinããå§ããŸãããã 誰ãããžã£ã¯ã«ã¯å€ãã®åé¡ããããšèšã£ãŠããŸãã島ã«ã¯ããããã®ç«å±±ããããå°éããããŸãã 圌女ã¯æãããå¿ èŠããããŸãã
ãã®ãããã³ããªã³ãšããå¥ã®å³¶ãæãæµ®ãã³ãŸãã
èœã¡çããŠãäœãèµ·ãããŸããã ããã¯éåžžã«å¹³ãã§ãç«å±±ã¯ãããŸããã è¿ãã«ãããŸãã ãããã£ãŠãKotlinã¯ãç¹ã«ç§ãã¡ã®ãããªAndroidéçºè ã«ãšã£ãŠãJavaã®æäžäž»ã§ãã
ã³ããªã³ã«ã€ããŠã®äžèš
ã³ããªã³ãšã¯ãå€ããå°ãªãã誰ããç¥ã£ãŠããããšã§ãã Kotlinãªãã§ä»æ¥Androidåãã«æžããŠããã®ã¯ã©ã®ãããªæãè ã§ããïŒ ããã¯ãç§ã«ã¯ãã§ã«ããŸããºã ã®ããã§ãã ããã¯çŽ æŽãããæ©èœããŸãã æ°é±éåãæåã®Kotlinãã€ãã£ããã«ãããªãªãŒã¹ãããŸããã ãŸããªããKotlinã§iOSã䜿çšããŠäœæããäºå®ã§ãã
ããã¯å®çšçãªèšèªããªãŒãã³ãœãŒã¹ãéåžžã«ã¯ãŒã«ãªãã¥ãŒãã³ã°ã§ã-IDEãããŸãæ©èœããããã«èšèšãããŠããŸãã ããã¯ãAppleã®Swiftèšèªãªã©ã®åºã«ããç³ã§ãã JetBrainsã¯åªããããã·ã¥åKotlinã§ããç¹ã«IDEçšã®èšèªãèšèšããŠããŸãã
Kotlinã®éçºã«ã¯éåžžã«é·ãæéãããã£ãããšã¯èª°ããç¥ã£ãŠããŸãã ããŒãžã§ã³1.0ããªãªãŒã¹ããããŸã§ã«6幎ãçµéããŸããã JetBrainsã¯äžçæžåœåªåããŸããããæããã«æ°ããèšèªãäœæããããšã¯ããã»ã©ç°¡åã§ã¯ãããŸããã éå»æ°å¹ŽéïŒ2010幎ãã2016幎ïŒã圌ãã¯ããŽãããçŸä»£çãªãã®ã«å€æŽããããšããã§ããŸããã
ã©ããããã®æééçºãããŠããããèãããšããã®èšèªã¯åªããŠããã¯ãã§ãã ä»ã®å€ãã®èšèªãã¯ããã«é«éã«éçºãããŠãããããããã¯äžçæé«ã®èšèªã§ããå¿ èŠããããŸãã ããšãã°ã誰ããJavaScriptã2é±éã§å®äºããããšãç¥ã£ãŠããŸãã ãã¡ãããããã¯ãã±ããç§åŠã§ã¯ãããŸãããïŒãã±ããç§åŠã¯SpaceXã§ããã4幎ã§å®éã®ãã±ããã®ãã©ãããã©ãŒã ã«çéžããããšãåŠã³ãŸããïŒã
ãããŠæãéèŠãªããšã¯ãKotlinããµã³ã¯ãããã«ãã«ã¯ã§éçºãããŠãããããããã·ã¢ã®æ°å°ãªãããã°ã©ãã³ã°èšèªã®1ã€ã§ããããã§ãã å€ããã·ã¢ã®ããã°ã©ãã³ã°èšèªã¯æ¬¡ã®ããã«ãªããŸããïŒå³åŽïŒïŒ
幞ããªããšã«ããã®èšèªã¯åœéçãªèŠèŽè ã察象ãšããŠããããããfuãããŒã¯ãŒãã®ä»£ããã«ãäœæè ã¯æ¥œããããŒã¯ãŒãã䜿çšããããšã決å®ããŸããã ããã¯æ¥œããèšèªã§ãã
ãžã°ãœãŒããºã«
ããºã«ã²ãŒã ãšã¯äœã§ããïŒ
ãããã¯èå³æ·±ãåäœãåããKotlinã§æžãããçãããã°ã©ã ã§ãã ãããŠãããªãã¯åœŒããå°å·ãããã®ãæšæž¬ããŸãã ææ¡ãããåçãªãã·ã§ã³ã«æ祚ãããšãæåã«æãæããŠæ£ãããªãã·ã§ã³ãæšæž¬ããã ãã§ãªãããã®çç±ã説æãã人ãè³åãåãåããŸãã
ããºã«ã®ååã¯ãKotlinã«ããŸã詳ãããªã人ã察象ãšããŠããŸãã åŸåã¯çéå ¥ãã®Kotlinéçºè åãã§ãã
Kotlinã¯ãæåãªJavaããºã«ã²ãŒã ã®ããã€ããç¹°ãè¿ããªãããšã§ç¥ãããŠããŸãã ãã ããçæ³çãªããã°ã©ãã³ã°èšèªã§ã¯ãããºã«ã¯ãŸã£ãããããŸããã Kotlinã¯å®å šã§ã¯ãªãããšãããããŸãã-å®å šãªèšèªã¯ãããŸããã
ããããKotlinã¯ãã§ã«å€ãã®ã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã§æ¡çšãããŠããŸãã ãã®èšèªã¯ãå€ãã®å Žåãå®çšçã§äŸ¿å©ãªãã®ãšããŠäœæãããŸããã 䜿ãããããå«ããŠäŸ¿å©ã§ãã ãããŠåœŒã¯ãŸã éçºäžã§ãã Kotlinã®éçºè ãšè©±ãããŠãã©ã®ããã«ãäœãä¿®æ£ãããã«ã€ããŠåæããããšãã§ããŸãã
å®èšŒæžã¿ã®ãã¹ãŠã®ããºã«ã¯ãKotlin 1.1.1-ææ°ã®å®å®ããŒãžã§ã³ã§èµ·åããŸãã ããºã«ã®ãœãŒã¹ã³ãŒãã¯GitHubã«ãããŸã-https: //github.com/angryziber/kotlin-puzzlers/tree/mobiusã§ç¢ºèªã§ããŸã ã
æ°ããããºã«ã²ãŒã ã®ã¢ã€ãã¢ãæãã€ãã人ã¯èª°ã§ãããã«ãªã¯ãšã¹ããéä¿¡ããŠãã ããã åŸ ã£ãŠããŸãã
ããºã©ãŒ1
Kotlinã¯ãnullå¯èœæ§ããµããŒãããŠãããšããç¹ã§åªããŠããŸããæ£ç¢ºã«ã¯ãnullã»ãŒãã§ãã
package p1_nullean val s: String? = null if (s?.isEmpty()) println("true")
nullableåãšnonnullableåã«ã¯éãããããŸãã ã€ãŸããnullãã©ããã«å²ãåœãŠãå Žåã¯ãnull蚱容åïŒè³ªåä»ãïŒã§ãªããã°ãªããŸããã ãã®ã¢ã€ãã¢ã¯ããããCïŒã«ãã£ãŠææ¡ãããŸãããã圌ã¯ãããå®æãããŸããã§ãã-ããªããã£ãã®ã¿ãããã§äœ¿çšå¯èœã«ãªããŸãã ãŸããKotlinã§ã¯ãããã¯ãã¹ãŠã®ã¿ã€ãã§ãã§ã«æ£åžžã«è¡ãããŠããŸãã åºæ¬çã«ããã®èšèªã¯ãå®è¡æã«æãããNullPointerExceptionãçºçããªãããã«èšèšãããŠããŸãã
ãã®äŸã§ã¯ãKotlinã¯åªãããã«ã»ãŒãæŒç®åsãæ¡çšããŠããŸããïŒGroovyããããŒãã§äœããã®ã¡ãœãããåŒã³åºãããšãã§ããå®è¡æã«ã¢ã¯ã·ã§ã³ãããã«ååŸã§ããŸããã
å¯èœãªãªãã·ã§ã³ã®ã©ããååŸãããèŠãŠã¿ãŸãããïŒ
- äœããªã
- æ¬åœ
- ãã«ãã€ã³ã¿ãŒåå
- ã³ã³ãã€ã«ããŸãã
å§ããŸãã èŠãŸãã
ã³ã³ãã€ã«ãããŸããã
ãªãã§ïŒ
Kotlinã¯åå®å šãªèšèªã§ãããããåŒsïŒ.IsEmptyïŒïŒã®çµæã¯nullã§ãããããfalseã«ãã£ã¹ããããŸããã
ç°¡åã«ä¿®æ£ã§ããŸãïŒKotlinãGroovyãšåãããã«åäœããããã«èšè¿°ããå¿ èŠããããŸãïŒã
if (s?.isEmpty() ?: false) println("true")
ããŸããããã§ã¯ãããŸããããä»ã¯ãããã§ãã Kotlinovskyãã©ãã«ãŒã¯ãnullãfalseãšè§£éããææ¡ããã§ã«æåºããŠããŸãããç¬èªã®ãã¥ã¢ã³ã¹ããããŸãã ãã®æ©èœãååŸãããã©ããã¯ãŸã äžæã§ãã ããŸããŸãªæèŠããããŸããããã®èšèªã䜿çšããããšã®å©äŸ¿æ§ã®èŠ³ç¹ãããããã¯å°ããªåé¡ã§ãã
ããºã©ãŒ2
ããºã«ã¯éåžžã«äŒŒãŠããŸããåãnullå¯èœãªæååå€æ°ãããããã®ã¡ãœãããåŒã³åºãããšããŠããŸãã
package p2_nulleanExtended val x: String? = null print(x.isNullOrEmpty())
çµæã¯ã©ããªããŸããïŒ
- æ¬åœ
- åœ
- ãã«ãã€ã³ã¿ãŒåå
- ã³ã³ãã€ã«ãããŠããŸãã
èµ·åäž...
çãã¯æ¬åœã§ãã
ãªãã§ïŒ ããã¯Kotlinæšæºã©ã€ãã©ãªã®æ¡åŒµé¢æ°ã§ããããã«å¯èœãªCharSequenceã«ããã³ã°ãããŸãã ãããã£ãŠããã®ãããªå Žåãæ£åžžã«åŠçãããŸãã
å®éãKotlinã§ã¯ãnullã§ããã€ãã®é¢æ°ãå®è¡ã§ããŸãã ã³ã³ãã€ã©ãŒã¯ãããèªèããŠããããŠãŒã¶ãŒã¯ãããè¡ãããšãã§ããŸãã
çå笊ãä»ãããšãIDEAã¯ãããããã§ã¯å¿ èŠãªãããšãæããŠãããŸãã
print(x?.isNullOrEmpty())
é¢æ°ã®ååã人åã«ãªã£ãŠããã®ã¯è¯ãããšã§ãïŒååã§çµæãæšæž¬ã§ããŸãïŒã
2çªç®ã®ãªãã·ã§ã³ïŒçå笊ä»ãïŒã§å®è¡ãããšãçµæã¯nullã«ãªããŸããããã¯ããã£ãå ã®åŒãnullã«ãã£ã¹ããããnullããµããŒãããŠããã«ãããããããã®é¢æ°ãåŒã³åºãããªãããã§ãã ã¡ãªã¿ã«ãããã¯å¥ã®ããºã«ã²ãŒã ã§ãã
ããºã©ãŒ3
package p3_platformNulls class Kotlin { fun hello(name: String) = print("Hello $name") } fun main(args: Array<String>) { val prop = System.getProperty("key") Kotlin().hello(prop) }
Kotlinã«ã¯ããã®ãããªèå³æ·±ãæ©èœããããŸã-ãã«å¯èœæ§ã®3çªç®ã®ç¶æ ã ãåŒã³åºããšã©ããªããèŠãŠã¿ãŸãããã
val prop = System.getProperty("key")
ãããŠããããKotlinã¯ã©ã¹ã®helloã¡ãœããã«æž¡ããŸããããã«ãããå°å·ãããã¯ãã§ãã
Kotlin().hello(prop)
åºåã¯äœã«ãªããŸããïŒ
- ããã«ã¡ã¯
- ããã«ã¡ã¯ãã«
- ã³ã³ãã€ã«ãããŠããŸãã
- ãªãã·ã§ã³ãªã
äžè¬ã«ãåæšè«ã¯çŽ æŽããããããã¯ã§ãã
å§ããŸãã IllegalStateExeptionãåãåããŸãã
ãªãã§ïŒ
propå€ã¯nullãã¿ã€ãã¯StringïŒã§ããhelloã«ãªããå®è¡æã«nullã§ãã£ãŠã¯ãªããªãããnullã§ããããšããã§ãã¯ãããŸãã
å®éãKotlinã®åæããŒãžã§ã³ã§ã¯ãStringãJavaããæ¥ãå Žåãããã©ã«ãã§ã¯åžžã«nullå¯èœã§ãã
val prop: String? = System.getProperty("key")
ããã¯ãJavaãšçžäºéçšãããšãã«ã³ãŒããæžãã®ãéåžžã«äžäŸ¿ã«ãªããšããäºå®ã«ã€ãªãããŸããã ãããŠãä»®æ³åã®æååãäœæããããšã«ããŸããïŒ ïŒæå笊ä»ãïŒã ããã¯nullabilityã®3çªç®ã®ãªãã·ã§ã³ã§ããããããããªãããšåŒã°ããŸãã
val prop: String! = System.getProperty("key")
ãã ããã¿ã€ãã¯æååã§ããããããã®ãããªã³ãŒãã¯ã³ã³ãã€ã«ãããŸããïŒ èªåã§å®£èšããããšã¯ã§ããŸããã Javaããã®ã¿ååŸã§ããŸãã
ãããã£ãŠããã®ãããªããšãäºåã«nullå¯èœãŸãã¯nulläžå¯ãšããŠå®£èšããããšããå§ãããŸãïŒååãšããŠãAPIããã¯ãnullããã€ãããã«æ¥ããã©ãããç¥ã£ãŠããŸãïŒã
ãã ãããã®ãããªã³ãŒãã¯ã³ã³ãã€ã«ãããŸãããå®è¡æã«ã¯ã©ãã·ã¥ããå¯èœæ§ããããŸãã
val prop: String = System.getProperty("key")
IDEAã¯ãã©ã®ã¿ã€ããã©ãã«ããããåžžã«ç¥ã£ãŠããŸãã å€æ°Ctrl + qãã¯ãªãã¯ããŠç¢ºèªã§ããŸãã
ããããnullabilityã§çµãããå¥ã®ãããã¯ã«ç§»ããŸãããã
ããºã©ãŒ4
å°å·ãã2ã€ã®é¢æ°ããããŸãã ããããçºè¡šããŠèµ·åããŸã-ãã¹ãŠãã·ã³ãã«ã§ãªããã°ãªããŸããïŒ
package p4_kotlinVsScala fun main1() = print("Hello") fun main2() = { print("Hello2") } main1() main2()
åºåã¯äœã«ãªããŸããïŒ
- ããã«ã¡ã¯
- ããã«ã¡ã¯2
- HelloHello2
- ã³ã³ãã€ã«ãããŠããŸãã
å§ããŸã...ããã«ã¡ã¯ã
ãªãã§ïŒ
Main1ã¯ãŠããããè¿ããŸãããprintïŒ "Hello"ïŒãåŒã³åºããŸãã ãããŠmain2ã¯ãå®è¡ãããªãã©ã ããè¿ãã ãã§ãã
次ã®ããã«ä¿®æ£ã§ããŸãã
main2()()
ç§ã®æèŠã§ã¯ã2çªç®ã¯ãmain2ããçå·ãåé€ããããšã§ããããã¯ãå šå¡ãæ··ä¹±ãããã ãã ããã§ãã
fun main2() { print("Hello 2") }
ãã®äŸãKotlin察ScalaãšåŒã¶ã®ã¯ãªãã§ããïŒ Scalaã§æžãã人ã¯ããã®ã³ãŒããäœããè¿ãé¢æ°ã®çµ¶å¯Ÿçã«æå¹ãªå®£èšã§ããããšãç¥ã£ãŠããŸãã
fun main2() = { }
Kotlinã§äœæãã貧匱ãªScalaéçºè ã 圌ãã¯ããããéå§ããããšãªãã©ã ããåžžã«è¿ããŸãã
ããºã©ãŒ5
æ°å€ã®ãªã¹ãããããforEachã¡ãœãããç¹°ãè¿ãåŠçããŸãã ForEachã¯ãGroovyãšåæ§ã«ãlambdaãã©ã¡ãŒã¿ãŒã宣èšãããŠããªãå ŽåããããèªèããŠããŸãã ãããŠãããã2以äžã§ããããšã確èªããå°å·ããŸãã
package p5_sneakyReturn fun main(args: Array<String>) { listOf(1, 2, 3).forEach { if (it > 2) return print(it) } print("ok") }
çµæã¯ã©ããªããŸããïŒ
- 123ok
- 12ok
- 12
- ç¡éã«ãŒã
èµ·åäž...
12
ãªããŠãã³ã»ã³ã¹ïŒ
Kotlinã§ã¯ãé¢æ°ããæ»ãå€ãè¿ãããŸãã ãŸããç¹å®ã®ã©ã ããçµäºããã«ã¯ããã®é¢æ°å ã§ãæ»ãåŸã«ã©ã ãã®ååãæå®ããå¿ èŠããããŸãã
if (it > 2) return@forEach
ãããã£ãŠãã©ã ãããæãåºãããšãã§ããŸãã Javaã§èšè¿°ããã©ã ãããæãåºãå¿ èŠãããå Žåãããã¯ã³ãŒããä¿®æ£ãããªãã·ã§ã³ã§ãã
å®éãKotlinã§ã®è¿åã¯ãæ¬æ¥ã®æ¹æ³ã§æ©èœããŸãã 以åã«CïŒãšJavaã§èšè¿°ããŠããªãã£ãå Žåãã¡ã€ã³é¢æ°ããæ»ãå€ãè¿ããããããããããééããããªãã£ãã ããã ãã¹ãŠãè«ççã§ãã ãŸããã©ã ãã«ã¯å¥åŠãªæ©èœã¯ãããŸããããäœããã®çç±ã§æãåºãå¿ èŠããããŸãã
ãªããã®ããã«æ©èœããã®ã§ããïŒ
forEaché¢æ°ã¯ãã€ã³ã©ã€ã³é¢æ°ãšããŠå®£èšãããŸãã Kotlinã§ã¯ãã³ã³ãã€ã©ã¯ã³ã³ãã€ã«ãããã³ãŒãã§ãã®é¢æ°ãåŒã³åºããŸãããããã®é¢æ°ã®ã³ãŒããååŸããåŒã³åºãããã£ãå Žæã«æ¿å ¥ããŸãã ãã®çµæãéåžžã®forã«ãŒããååŸãããã¡ãããã¡ã€ã³é¢æ°ãçµäºããŸãã
ãããã€ã³ã©ã€ã³é¢æ°ã§ããããšãç解ããæ¹æ³ã¯ïŒ ãŸããIDEAã«ã¯Ctrl + pããããŸãã 次ã«ãreturnãåŒã³åºããé¢æ°ãã€ã³ã©ã€ã³ã§ãªãå Žåãã³ã³ãã€ã©ãŒã¯ãããããããã¯ã§ããŸããããšèšããŸãã ã€ãŸããã³ã³ãã€ã©ã¯ãã³ã»ã³ã¹ãè¡ãããšãèš±å¯ããŸããã
12okãè¿ãããã«ãã®ã³ãŒããä¿®æ£ããå¥ã®ãªãã·ã§ã³ããããŸãã ããã¯ãã©ã ãã§ã¯ãªãé¢æ°ãšããŠå®£èšããå¿ èŠããããŸãã
fun main(args: Array<String>) { listOf(1, 2, 3).forEach(fun() { if (it > 2) return print(it) }) print("ok") }
å¿åé¢æ°ãšã©ã ãã䜿çšããKotlinã®å¯äžã®éãã¯ãæåã®é¢æ°ãé¢æ°ãšãŸã£ããåãããã«åäœããããšã§ããã€ãŸããreturnã¯æãè¿ããfunãïŒfunïŒããæ»ããŸãã ãããã£ãŠããã®ä¿®æ£ã«ãããæ£åžžã«æ©èœããŸãã
ããã«èå³æ·±ããã®ã«ããããã«ãããã€ãã®äŸãçšæããŸããã Kotlinã«ã¯ããŸããŸãªããŒã¯ãŒãããããŸãã
- 楜ãã
- ã€ã³ã©ã€ã³æ¥œãã
- noinline lambdaã«ããã€ã³ã©ã€ã³ã®æ¥œãã¿
- lambda crossinlineã®ã€ã³ã©ã€ã³ã®æ¥œãã¿
ãããã®ããã€ãã¯ãreturnã䜿çšããããšãèš±å¯ããããã€ãã¯èš±å¯ããŸããã
package p5_sneakyReturn fun hello(block: () -> Unit) = block() inline fun helloInline(block: () -> Unit) = block() inline fun helloNoInline(noinline block: () -> Unit) = hello(block) inline fun helloCrossInline(crossinline block: () -> Unit) = runnable { block() }.run() fun main(args: Array<String>) { hello { println("hello") //return - impossible } hello(fun() { println("hello") return }) helloInline { println("hello") return } helloNoInline { println("hello") //return - impossible } helloCrossInline { println("hello") //return - impossible }
宿é¡ãç§ãã¡ã¯Crossinlineãäœã§ããããç解ãã欲æ±ãæ®ããŸãã é¢çœããšæããŸãã
Kotlinã§æžãå§ããã°ããã®ãšããç§ã¯ãããè€éãªãã®ã ãšæããŸããã ããããã€ã³ã©ã€ã³é¢æ°ãäœã§ããããç解ãããšïŒã³ã¬ã¯ã·ã§ã³ã®ã»ãšãã©ãã¹ãŠã®æ¡åŒµé¢æ°ã¯ããã©ãŒãã³ã¹ã®ããã«ã€ã³ã©ã€ã³ã«ãªããŸãïŒããã¹ãŠãéåžžã«è«ççã«ãªããŸãã
ããºã©ãŒ6
ãžã§ã³ãŸãã¯ãžã£ã¢ã³ãååŸããå¿ èŠããããŸãã
åçŽãªPersonã¯ã©ã¹ããããŸãã Kotlinã§ã¯éåžžã«äŸ¿å©ã§ããã¯ã©ã¹ã宣èšãããšãã«ãã³ã³ã¹ãã©ã¯ã¿ãŒãããã«å®£èšã§ããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒå€æ°åãååŸãããããããããã£ã«è¿œå ããŸãã Kotlinã«ã¯ãã£ãŒã«ãããããŸãããã²ãã¿ãŒãã»ãã¿ãŒãããããçš®é¡ã®ãã³ã»ã³ã¹ïŒãŸãã¯CïŒã®ããã«gethãšsetïŒãèšè¿°ããå¿ èŠããªããããããããã£ã®ã¿ããããéåžžã«ã¯ãŒã«ã§ãã ãã°ãããçŸããæ§æã
ãã®çµæãJohnãšããååã®PersonãäœæãããããJaanã®ãšã¹ããã¢èªããŒã«ãªãŒãŒã·ã§ã³ã«å€ãããã©ããã確èªããŸãã
package p6_getMeJohn class Person(name: String) { var name = name get() = if (name == "John") "Jaan" else name } println(Person("John").name)
- ãžã§ã³
- ãžã£ãŒã³
- ã³ã³ãã€ã«ãããŠããŸãã
- ãªãã·ã§ã³ãªã
èµ·åäž...
ããã¯ã¹ã¿ãã¯ãªãŒããŒãããŒã§ãã
ãªãã§ïŒ
ååãåããif-elseã«ããgetã§åŒã³åºããŸãã ä¿®æ£ããã«ã¯ãããããã£ã§ã¯ãªããã£ãŒã«ããåç §ããå¿ èŠããããŸãã fieldããŒã¯ãŒãã䜿çšã§ããŸãïŒ
class Person(name: String) { var name = name get() = if (field == "John") "Jaan" else field }
Kotlinã®ãã£ãŒã«ãããŒã¯ãŒãã§ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ã§ããŸããããããè¡ãããšãã§ããå¯äžã®å Žæã¯ã²ãã¿ãŒ/ã»ãã¿ãŒå ã§ãã ä»ã®ãã¹ãŠã®åŒã³åºãã¯ãããããã£ãä»ããŠã®ã¿è¡ãããŸã-ãã£ãŒã«ãã«çŽæ¥ã¢ã¯ã»ã¹ããŸããã
圌ãã¯ã.NETä»®æ³ãã·ã³ãšã¯ç°ãªããJava Hotspotã³ã³ãã€ã©ãŒããããæé©åãããããããã©ãŒãã³ã¹ã¯ãã¹ãŠã¯ãŒã«ã§ããããã¹ãŠãéåžžã«é«éã«åäœãããšèšããŸãã
ããºã©ãŒ7
ç¹°ãè¿ãã«ãªããŸãããèšèªã®çŽ æŽãããæ©èœ-åæšè«-ãèŠãŠãã©ããªåã®whatAmIã§ãããŸããŸããããšã«ããããã䜿çšã§ããŸãã ããããã³ã³ãã€ã©ã¯ãããäœã§ããããç¥ã£ãŠããŸãã ç¥ã£ãŠãããã©ããèŠãŠã¿ãŸãããã
package p7_whatAmI val whatAmI = {}() println(whatAmI)
ã©ã®ãªãã·ã§ã³ãçµæã«ãªããŸããïŒ
- kotlin.jvm.functions.Function0
- ïŒïŒ-> kotlin.Unit
- kotlin.Unit
- äœããªã
å®è¡... kotlin.UnitãååŸããŸãã
ãªãã§ïŒ
ããã§ã©ã ãã宣èšãããã©ã ããåŒã³åºãããŸãã lambdaã¯äœãè¿ããªãïŒæ£ç¢ºã«ã¯kotlin.Unitãè¿ãïŒããããããåºåãããŸãã ãããŠããŠãããã®æè¯ã®å®çŸ©ã¯ç¡å¹ã§ãã
ãŠãããã¯ã©ãããæ¥ãã®ã§ããïŒ ç§ã®æèŠã§ã¯ãæ°åŠïŒãŸãã¯ã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ïŒã§ããåçè«ã®ãããªãã®ããããŸãã ãŸããUnitã¯ãäœããªãããšããæå³ã®1ã€ã®èŠçŽ ã§ãããšèª¬æãããŠããŸãã ãããã£ãŠãäžéšã®ã¢ã«ãããã¯ããã°ã©ãã³ã°èšèªã§ã¯ããŠããããšããçšèªã䜿çšããŸãã Kotlinã¯å®çšçãªèšèªãšããŠèšèšãããŸããããããã«ããããããããã®éçºè ã¯å®çšçãªãã€ããéžæããââãUnitãäœæããããšã«ããŸããã
ããã«ãããããããããã«ãKotlinã«ã¯kotlin.Nothingãšããå¥ã®ã¿ã€ãããããŸãã
ãããã¯ã©ãéãã®ã§ããïŒ ãã®è³ªåã«å¯Ÿããçãã宿é¡ã«ããŸãã
ããºã©ãŒ8
whatAmIãèŠãŠãä»iAmThisããããŸãã
ããã§ã¯ãã¹ãŠãå°ãè€éã§ãïŒIââAmã¯ã©ã¹ããããããã¯ããŒã¿ã¯ã©ã¹ã§ãïŒããã¯Kotlinã®çŽ æŽãããæ©èœã§ãããçãããhashCodeãtoStringãããã³ãã¹ãŠã®ãã®ãã€ã©ãŒãã¬ãŒããèªåçã«çæããŸãã Scalaã§ã¯ãããã¯ã±ãŒã¹ã¯ã©ã¹ã§ããå®éã誰ããæ£ç¢ºã«ããŒã¿ã¯ã©ã¹ãšããŠäœ¿çšããŠããŸããããã®ååã¯ãã£ãšæªãã§ãã
IAmã¯ã©ã¹ã«ã¯ããã£ãŒã«ãfooã宣èšããã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãã Fooã¯åæã«ããããã£ã§ãããããhelloïŒïŒé¢æ°ãšãšãã«äœ¿çšã§ããŸãã
ããã«æååãbarããæž¡ããhelloé¢æ°ãåŒã³åºããŠãäœãè¿ããããã確èªããŸãã
package p8_iAmThis data class IAm(var foo: String) { fun hello() = foo.apply { return this } } println(IAm("bar").hello())
åºåã§ã¯äœãåŸãããŸããïŒ
- IAm
- IAmïŒfoo = barïŒ
- ããŒ
- ã³ã³ãã€ã«ãããŠããŸãã
éå§ããŸã...ããŒãåãåããŸã
ãªãã§ïŒ
Applyã¯ããªãããŒãªæ¡åŒµæ©èœã§ãã ã©ã ããåãåãããã®äžã«ã©ã ããåŒã³åºããŠãããã«å¯ŸããŠããã€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ãããªããžã§ã¯ããèš±å¯ããŸãã ãããã£ãŠãããã¯ããŒã§ãã ãããŠãããã«ã¡ã¯ã¯ããŒã§ãã
ãã®ç¹ã§ãKotlinã¯JavaScriptã«äŒŒãŠããŸãã JavaScriptã®ããã«ãKotlinã§ã¯ããããäœã§ããããããããªããªã£ãç¶æ ã«å°éã§ããŸãã
äžè¬çã«ãå€ãã®äŸ¿å©ãªé¢æ°ããããŸãïŒãŸããletãwithã
ååãšããŠããããã¯ãã¹ãŠããªãç°ãªããŸãã
ããšãã°ãapplyã¯ã絶察ã«ãã¹ãŠã®åïŒnulläžå¯ïŒã®æ¡åŒµé¢æ°ã§ãã ã©ã ããåãå ¥ããŸããããã®ã©ã ãã¯å€éšãªããžã§ã¯ãã§ã¯ãªãå éšTã«ã¢ã¿ãããããããéåžžã«ããªãããŒã§ãïŒãã®ã©ã ãã«ã¯ç¬èªã®TããããŸãïŒã ããªãã¡ é¢æ°ã¯thisã§ãã®ã©ã ããåŒã³åºããthisãè¿ããŸãïŒããã圹ç«ã€å ŽåããããŸãïŒã
ä»ã«ãæ©èœããããŸãã ã³ãŒãã¯æ¬¡ã®ããã«ä¿®æ£ã§ããŸãã
package p8_iAmThis data class IAm(var foo: String) { fun hello() = foo.let { return it } } println(IAm("bar").hello())
ãããããšãç®ç«ããªããªããŸãã
å Žåã«ãã£ãŠã¯ãé©çšã¯éåžžã«äŸ¿å©ãªæ©èœã§ãã ããããã³ãŒããéåžžã«ãã°ããèŠããšïŒãããŠæåã®ããŒãžã§ã³ã®èšé²ã䜿çšãããŠããå ŽåïŒãæ··ä¹±ããå¯èœæ§ããããŸãã
æåã®ãªãã·ã§ã³ã§ã¯ã次ã®ããã«ã³ãŒããççž®ã§ããŸãïŒé©çšé¢æ°ã¯ããèªäœãè¿ããããäœãå€æŽãããŸããïŒã
data class IAm(var foo: String) { fun hello() = foo.apply { } }
ããºã©ãŒ9
ãã§ã«ç¥ã£ãŠããleté¢æ°ãèŠãŠã¿ãŸãããã
ã«ããããã±ãã³ã»ã¢ã¹ããéã£ããã®ããºã«ã åŒæ°ã®ç¬Šå·ïŒIntïŒãåºåããåçŽãªé¢æ°ããããŸãã
package p9_weirdChaining // by Kevin Most @kevinmost fun printNumberSign(num; Int) { if (num < 0) { "negative" } else if (num > 0) { "positive" } else { "zero" }.let { println(it) } } printNumberSign(-2) printNumberSign(0) printNumberSign(2)
ãã®ãããªã³ãŒãã¯äœãå°å·ããŸããïŒ
- è² ã® ãŒã; ããžãã£ã
- è² ã® ãŒã
- è² ã® ããžãã£ã
- ãŒã; ããžãã£ã
éå§...åºå£ã§-ãŒã; ããžãã£ãã
åé¡ã¯äœã§ããïŒ
ifã¯å®éã«ã¯åŒã§ãã ã€ãŸãã2ã€ã®åŒãååŸãããletã¯2çªç®ã®åŒã«ã®ã¿é©çšãããŸãã
Kotlinã§ããããæžãããããã®ããºã«ã¯æ±ºå®ããªãã£ãã ããã¯ããçš®ã®å°çã®ãããªãããã¯ã§ãã ååã®JPointã«ã³ãã¡ã¬ã³ã¹ã§ã¯ãã³ã³ãã€ã©ã®ãã°ã ãšããèããŠããŸããã ããããAndrei Breslavã«å°ãããšãããããã¯åãªãããŒãµãŒãã¥ã¢ã³ã¹ã§ããããšãããããŸããã
ä¿®æ£æ¹æ³ ç°¡å-ãã£ããä»ããã ãïŒ
fun printNumberSign(num; Int) { (if (num < 0) { "negative" } else if (num > 0) { "positive" } else { "zero" }).let { println(it) } }
次ã«ãletãåŒå šäœã®çµæã«é©çšããŸãã æåã®ã±ãŒã¹ã§ã¯ãã³ãŒãã¯æ¬¡ã®ããã«æ©èœããŸããã
fun printNumberSign(num; Int) { if (num < 0) { "negative" } else (if (num > 0) { "positive" } else { "zero" }).let { println(it) } }
åæã«ãäžã®åŒã¯å¥ã ã«ãªããŸã-leté¢æ°ã¯ããã«é©çšãããŸããã
Kotlinã«ã¯elseifæŒç®åã¯ãããŸããïŒååšããå Žåããã®ããºã«ã¯ååšããŸããã§ããïŒã
ãã¹ãŠã®ããºã«ã²ãŒã ãšåæ§ã«ãã¢ã©ã«ã¯ããã§ãããã®ãããªã³ãŒããæžããªãã§ãã ããã è€éãªæäœïŒãããªã©ïŒãè¡ãå Žåã¯ããã£ããå ¥ããããå€æ°ã«å ¥ããŠããletãåŒã³åºããŠãã ããã
ããºã©ãŒ10
ããã«é¢çœãããºã«ã²ãŒã ã ããããã®ã³ãŒãããããŸãã
ãã®ããºã«ã²ãŒã ã¯ããããšã«ã»ãããã£ã³ã®ã¶ãããã£ã«ã§ãã ããã¯ãKotlinã®éåžžã«ã¯ãŒã«ãªæ©èœ-ããªã²ãŒãããããã£ã®ããºã«ã§ãã Kotlinã§ã¯ãããšãã°ãã¯ã©ã¹ã«è€æ°ã®ããããã£ãããããããããã£ãŒã«ããšããŠã§ã¯ãªããããããããã«ãã¯ã¢ãããšããŠå®è£ ãããŠããããšã宣èšã§ããŸãã
ã¯ã©ã¹Population-æ¯éå£ããããŸãã ãããŠãéœåžã¯ç§ãã¡ã«äžããŸãïŒvar cityïŒMap <StringãInt>ïŒãããŠããããããã®ãããã«å§ä»»ããŸãã
ããã«ãããå®éã«KotlinãJavaScriptã«å€æããããŒã¿ãååŸã«ã³ããŒããããšãªããããåçãªæ§é ãäœæã§ããŸãã ãã®ãããªã¯ã©ã¹ã¯å€ãã®ã³ãŒããåæžããŸãã
次ã«ãPopulationã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããã¹ãŠã®éœåžã®äººå£ããã®ã¯ã©ã¹ã«æž¡ããŸãã
ä»ãäœå¹Žãçµã£ããšæ³åããŠãã ããã 人ã ã¯å°çãæ±ãã-ç«æã«äœãããã«é£ã³å»ã£ãã ãããã£ãŠã人å£ã®ããå°å³ãç Žæ£ããŸãã
åã«èŠãwithé¢æ°ããããŸãã æ¯éå£ãååŸããããã«é¢é£ãã䜿çšå¯èœãªãã£ãŒã«ãã解決ããŸãïŒååãšããŠãé©çšãšåæ§ïŒã
package p10_mappedDelegates // by Daniil Vodopian @voddan class Population(var cities: Map<String, Int>) { val tallinn by cities val kronstadt by cities val st_petersburg by cities } val population = Population(mapOf( "st_petersburg" to 5_281_579, "tallinn" to 407_947, "kronstadt" to 43_005 )) // Many years have passed, now all humans live on Mars population.cities = emptyMap() with(population) { println("$tallinn; $kronstadt; $st_petersburg") }
ãã¹ãŠãç°¡åã§ãã 誰ããç«æã«é£ã¶ãšãã«ç§ãã¡ã®å°çã«äœãèµ·ããããç解ããã ãã§ãã ãã®ãããªã³ãŒãã¯äœãçæããŸããïŒ
- 0; 0; 0
- 407947; 4,3005; 5281579
- ãã«ãã€ã³ã¿ãŒåå
- NoSuchElementException
ç§ãã¡ã¯å§ããŸã...人ã ã¯ã©ãã«ã姿ãæ¶ããŠããªãããšãããããŸãïŒç«æã«äœãããšã¯éåžžã«é£ããã®ã§ãç§ãã¡ã¯å°çã«ãšã©ãŸãã§ãããïŒã
ãªãã§ïŒ
Population.cities = emptyMapïŒïŒã¯ã¯ã©ã¹ã®ç©ºã®ããããäœæããŸãããã€ã³ã¹ã¿ã³ã¹ã®ãããã¯äœæããŸããã ãã®ãããªã³ãŒããå€æŽããå ŽåïŒMutableMapãäœæããKronstadtãpopulation.kronstadt = 0ã«ãªã»ããããŸãïŒïŒ
class Population(var cities: MutableMap<String, Int>) { val tallinn by cities var kronstadt by cities val st_petersburg by cities } val population = Population(mutablemapOf( "st_petersburg" to 5_281_579, "tallinn" to 407_947, "kronstadt" to 43_005 )) // Many years have passed, now all humans live on Mars population.kronstadt = 0
ã³ãŒãã¯407947ãåºåããŸãã 0; 5281579
ããããç§ãã¡ã¯ãŸã æåã®ãªãã·ã§ã³ïŒcpopulation.cities = emptyMapïŒïŒïŒã«ã€ããŠè°è«ããŠããŸãã
ããªã²ãŒããå®è¡ãããšããããåç §ãïŒããããã®ïŒã²ãã¿ãŒå ã«èšæ¶ãããŸãã ãŸããéœåžãžã®ãªã³ã¯ãå€æŽããŠããã²ãã¿ãŒå ã®ãªã³ã¯ã¯å€æŽãããŸããã ããããç§ãã¡ã¯éœåžå ã®éœåžã«äœãä»ã®ãã®ã眮ãããšããã§ããŸãããããŠããã¯åãå°å³ãžã®ãªã³ã¯ã®ãŸãŸã§ããã®ã§ããã¹ãŠã¯æ©èœããŸãã ããããå¥ã®ããããžã®åç §ãå€æŽãããšããã®ãããã¯æ©èœããªããªããŸãã
ããºã©ãŒ11
ãšã¹ããã¢ã§ã¯ããè¯ãåã«ã¯å€ãã®ååããããŸãããšããåªããæ ŒèšããããŸãã
ããã§ããããã©ã®ããã«ã¯ã©ã¹ã«é©çšãããããèŠãŠã¿ãŸãããã
Kotlinã«ã¯ãã®ãããªå¥åŠãªãã¥ã¢ã³ã¹ããããŸããããã©ã«ãã®ã¯ã©ã¹ã¯finalã§ãããæ¡åŒµããããšã¯ã§ããŸããã ãŸã ããããæ¡åŒµããããšãã§ãããªãŒãã³ãªããŒã¯ãŒãããããŸãã
ã¯ã©ã¹Cã®ãã®ããºã«ã«ã¯ãopenã¡ãœããããããŸãïŒãã®ãããèªèšŒã§ããŸãïŒã ããã§ã¯ãxãšyã䜿çšããŸãïŒãããã«ã¯ããã©ã«ãå€ããããŸã-ããã¯èšèªã®éåžžã«åªããæ©èœã§ãïŒã
ã¯ã©ã¹Cãæ¡åŒµããsumé¢æ°ããªãŒããŒã©ã€ãããã¯ã©ã¹DããããŸãããååãšããŠãã¹ãŒããŒå®è£ ãåŒãèµ·ããããšãé€ããŠãæçšãªããšã¯äœããããŸããã
次ã«å€æ°dããããŸã-ã¯ã©ã¹Dã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã å€æ°cããããåãã€ã³ã¹ã¿ã³ã¹ãå²ãåœãŠãŸãïŒã¯ã©ã¹Dã®åãã€ã³ã¹ã¿ã³ã¹ãžã®2ã€ã®åç §ãååŸããŸãïŒã ãããŠãåºæ¬çã«åããªããžã§ã¯ãã§åãã¡ãœãããåŒã³åºããŸãã
package p11_goodChildHasManyNames open class C { open fun sum(x: Int = 1, y: Int = 2): Int = x + y } class D : C() { override fun sum(y: Int, x: Int): Int = super.sum(x, y) } val d: D = D() val c: C = d print(c.sum(x = 0)) print(d.sum(x = 0)) println()
æåŸã«äœãåŸãããŸããïŒ
- 22
- 11
- 21
- ã³ã³ãã€ã«ãããŠããŸãã
å§ããŸã...æ£è§£ã¯21ã§ãã
äœãèµ·ãã£ãŠããã®ããç解ããã®ã«åœ¹ç«ã€ããã€ãã®èŠåããŸã ããã«ãããŸãã
ã©ã¡ãã®å Žåããããªã¢ãŒãã£ãºã ã®ããããªãŒããŒã©ã€ããããé¢æ°ãåŒã³åºãããŸãã å®éã«ã¯cãšdã®äž¡æ¹ãã¯ã©ã¹Dã®ã€ã³ã¹ã¿ã³ã¹ã§ãããããå®è¡æã«åŒã³åºãããé¢æ°ãéžæãããŸãããã ããJVMã«ã¯ååãã©ã¡ãŒã¿ãŒãªã©ã®æ©èœããªããããã³ã³ãã€ã«æã³ã³ãã€ã©ãŒã¯ãããã解決ããŸãã ããªãã¡ å®è¡æã«é¢æ°ãéžæãããŠåŒã³åºãããã³ã³ãã€ã«æã«ãã©ã¡ãŒã¿ãŒãéžæãããããšãããããŸãã ãããã£ãŠã眮æãããã©ã¡ãŒã¿ãŒã¯ãå®è¡æã«ååŸãããªããžã§ã¯ãã§ã¯ãªããå€æ°ã®ã¿ã€ãã«ãã£ãŠç°ãªããŸãã ããã¯ããã§ãã ååãæ··åããŠã¯ãªããªãããšãèŠåããã³èŠåããŸããé¢æ°ããªãŒããŒã©ã€ããããšãã¯ãå¥ã®æ¹æ³ã§åŒã³åºãå¿ èŠããããŸãã
è¯ããã¥ãŒã¹ã¯ãæ瀺ãããããºã«ã®çŽååã«ã€ããŠãIDEAã¯ãã§ã«èŠåãçºããŠããããšã§ãã JetBrainsèªäœãããŒã«ã«åŸäºããŠãããšããäºå®ã®ãããå€ãã®ãšã©ãŒãåé¿ããã®ã«éåžžã«åœ¹ç«ã¡ãŸãã ãããããã¹ãŠã§ã¯ãããŸããã äžéšã®ããºã«ã§ã¯ãèŠåã¯ãŸã£ããäžå¯èœã§ãã
ãã ããèšèªã¯é²åããŠããŸãã 2016幎ãç§ãæžãå§ããã°ããã®ãšããIDEAã§ã®æ€æ»ã¯ã¯ããã«å°ãªãããããã®ããºã«ããŸãšããã®ã¯ã¯ããã«ç°¡åã§ããã çŸåšãç¶æ³ã¯ãŸã£ããç°ãªããŸããããŒãžã§ã³1.1ããªãªãŒã¹ãããå€ãã®ããããªãªãŒã¹ããããå€ãã®æ€æ»ãIDEAã«è¿œå ãããKotlinã§æ£ããç°¡åã«èšè¿°ã§ããããã«ãªããŸããã
çµè«ã®ä»£ããã«ãã³ããªã³ã«è¡ããŸãããã
- Androidã§ã¯ãéåžžã®Java 8ã¯ãŸã ãããŸãããKotlinã§ã¯ãJava 8ãªã©ã®ãã¹ãŠã®æ©èœãå©çšã§ããŸãã ããªãã¯ãã£ãšèªåèªèº«ãè¡šçŸã§ããŸãã
- Kotlinã¯å€§ããªèªå€§åºåã®ãªãèšèªã§ãã ããã圌ã®ãã©ã¹ã§ãã
- å€ãã®å ŽåãAndroidã§ã¯ãSwiftããšåŒã°ããŸãã ãã ããSwiftã«ã¯å°ããªåé¡ããããŸããæ°ããããŒãžã§ã³ããªãªãŒã¹ããããããã¹ãŠã®ã³ãŒãã絶ããæžãçŽãå¿
èŠããããŸãã Kotlinã«ã¯ãã®ãããªåé¡ã¯ãããŸããããœãŒã¹ã¬ãã«ãšãã€ããªã¬ãã«ã®äž¡æ¹ã§äžäœäºææ§ãä¿èšŒãããŠããŸãã
- Kotlinã¯Scalaãããã¯ããã«é«éã«ã³ã³ãã€ã«ãããŸãã Scalaããããã£ãšç°¡åã§ãã
- Groovyãããå®è¡æã®æ¹ãã¯ããã«é«éã§ãã Androidã«ã¢ããªã±ãŒã·ã§ã³ãè¿œå ãããšããµã€ãºã¯Javaãšæ¯èŒããŠ600 Kbã ãå¢å ããŸããããã¯Scalaãšæ¯èŒããŠéåžžã«å°ããã§ãã ãããã£ãŠãããã«æžã蟌ãããšã¯çã«ããªã£ãŠããŸãã
- ç§ãããã«åãæ¿ãããšããç§ã¯æåã®æ¥ããçç£çã«ãªãå§ããŸããã
- 圌ãã¯Kotlinã«ã€ããŠãããã¯ãããè¯ãGroovyãã§ãããåªããæ©èœããããšèšããŸãã
- IDEAã®äž»ãªå人ã¯Ctrl + Alt + Shift + Kã§ããããã¯ãJavaã¯ã©ã¹ãïŒãã®ãŸãŸïŒKotlinã«çŽæ¥å€æããŸãããã ããCtrl + Alt + Shift + Jããªããããæ¢ã«æ»ãããšã¯ã§ããŸãã-ããã¯äžæ¹éè¡ã§ããåž°ããããªã
- ãŸãGradleã«ãªããŸãã
æ°ããããºã«ãéã£ãŠã次ã®ã«ã³ãã¡ã¬ã³ã¹ã§æ¥œãã¿ãŸãããã
ããã°ã©ãã³ã°ã€ã³ããªã¢ã倧奜ãã§ãKotlinã«å®å šã«æ²¡é ãããå Žåã¯ã次ã®Mobius 2017ã¢ã¹ã¯ã¯äŒè°ã§çºè¡šããããããã®ã¬ããŒãã«æ³šæããããšããå§ãããŸãã
- Javaã«åªããKotlinã³ãŒãã®äœæïŒSergey Ryabovãç¬ç«ïŒ
- Kotlinã®äžçã§ã®ããŒã¿ãã€ã³ãã£ã³ã°ïŒLisa WrayãNew York TimesïŒ
- â ( , Badoo)