2016/12/13の30分 Kotlinメモ🐝
2016/12/13の30分 Kotlinメモ🐝
書いてるコードは雑にここにあります。
引き続き Calling Java code from Kotlin読んでる
https://kotlinlang.org/docs/reference/java-interop.html#getters-and-setterskotlinlang.org
Mapped types
Javaの型がKotlinの型にどうマッピングされるか書いてある。
興味深いのはCollectionの扱い。
JavaのCollectionは(Mutable)Collection<T>!
型になると。。。
Listなら(Mutable)List<T>!
ね。
ということは、以下のコードみたいにJavaで不変なListを作った場合に、Kotlinから見ると(Mutable)List<T>!
になるから、変更できるように見れるかー。
public class JavaJava { public List<String> getList() { return new ArrayList<>(); } public List<String> getUnmodifiableList() { return Collections.unmodifiableList(new ArrayList<>()); } } // Kotlin fun run() { val java = JavaJava() println(java.list) // (Mutable)List<T>! // JavaからKotlinへ不変なListであることは伝えられない?? java.unmodifiableList.add("") // UnsupportedOperationException }
JavaからKotlinへ不変なListであることは伝えられない??
頻繁に困る問題ではなさそうだけど...なくはないかなーと。
Java Arrays
とりあえずざっくり読んで、ほえーってなった。
読んでおくと良さそう。
Nullability annotations
JavaからのNullの扱い。
@Nullable
と@NotNull
をJavaのメソッドなどにつければ、Kotlinで参照する時にKotlin Typesになるよってこと。
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class JavaJava { @Nullable public String getNullableObject() { return null; } @NotNull public String getNotNullableObject() { return "not null"; } } // Kotlin val java = JavaJava() // @NullableをつけることでPlatform TypesじゃなくてKotlin typesになる println(java.nullableObject?.toUpperCase()) // @NotNullをつけることでPlatform TypesじゃなくてKotlin typesになる println(java.notNullableObject.toUpperCase())
Kotlinやりぞ!って気持ちがあったりする人々は、Javaのコードに積極的に付けていくと良さそう。
Optional
も変換してくれると嬉しいけどなー
import java.util.Optional; public class JavaJava { public Optional<String> getStringOptional() { return Optional.empty(); } } // Kotlin val java = JavaJava() // String?とかになってほしい... java.stringOptional.ifPresent { println(it) }
対応してるannotationsの種類なドキュメント見るなり、Kotlin compiler source code見るなりしてねーってらしい。
Androidのcom.android.annotations
と android.support.annotations
も対応してるのか。嬉しい。
まとめ
Optional
氏〜🤔
2016/12/12の30分 Kotlinメモ🍜
2016/12/12の30分 Kotlinメモ🍜
書いてるコードは雑にここにあります。
Calling Java code from Kotlin
Getters and Setters
JavaのクラスのメソッドでsetXXXとgetXXXがあるやつは、Kotlin側でプロパティみたいに扱えるよ!って話かな??
例としか以下みたいなコードが書いてある。なるほど、便利。
setterとかgetterしかないものはダメっぽい。
import java.util.Calendar fun calendarDemo() { val calendar = Calendar.getInstance() if (calendar.firstDayOfWeek == Calendar.SUNDAY) { // call getFirstDayOfWeek() calendar.firstDayOfWeek = Calendar.MONDAY // call setFirstDayOfWeek() } }
Escaping for Java identifiers that are keywords in Kotlin
Kotlinの予約語とかをもしJavaのメソッドとかで使ってる場合、``で囲んでねって話。
public class JavaJava { public void is() { System.out.println(JavaJava.class.getName()); } } JavaJava().`is`()
Null Safety
みんな大好きnull
の話。
これよくまとまってるので、ちゃんと読むと良さそう。
Nullable types and Non-Null Types
なるほど。
var hunhunhunhun: String = "abc" hunhunhunhun = null // compilation error println(hunhunhunhun.length) var hunhunhunhun2: String? = "abc" hunhunhunhun2 = null // OK println(hunhunhunhun2.length) // compilation error
Safe Calls
?.
ね。
続けても書ける。その場合、どこかでnullになればnullが返る。
var hunhunhunhun2: String? = "abc" hunhunhunhun2 = null // OK val len: Int? = hunhunhunhun2?.length println(len) val len2: Int? = hunhunhunhun2?.length?.toInt() println(len2)
let
と組み合わせて以下のようなこともできると。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html
val listWithNulls: List<String?> = listOf("A", null) for (item in listWithNulls) { item?.let { println(it) } // prints A and ignores null }
Elvis Operator
?:
ね。三項演算子みたいだけど違うよ、全然違うよ。
var hunhunhunhun2: String? = "abc" hunhunhunhun2 = null // OK // こうも書けるけどー println(if (hunhunhunhun2 != null) hunhunhunhun2.length else -1) // Elvis Operator使ってこう書いた方がいい println(hunhunhunhun2?.length ?: -1)
例外も投げられる。なので引数チェックとかに便利だよーって書いてあった気がする。
println(hunhunhunhun2?.length ?: throw Exception("hunhunhunhun2 is null."))
The !! Operator
!!
で無視してアクセスできると。これはーまあ使わないかなーできるだけ。
var hunhunhunhun2: String? = "abc" hunhunhunhun2 = null // OK println(hunhunhunhun2!!.length)
Collections of Nullable Type
こんなのもあるよー的な。
val nullableList: List<Int?> = listOf(1, 2, null, 4) val intList: List<Int> = nullableList.filterNotNull() println(intList) // [1,2,4]
実装的には単純だよね。
/** * Appends all elements that are not `null` to the given [destination]. */ public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C { for (element in this) if (element != null) destination.add(element) return destination }
まとめ
Null Safetyがよくまとまってて嬉しい😊
2016/12/11の30分 Kotlinメモ🎉
2016/12/11の30分 Kotlinメモ🎉
書いてるコードは雑にここにあります。
"Unsafe" cast operator
Castっすね。
Castできないと例外が起きるよーん。Nullableじゃないとnullでも落ちるよーん。
val iii = 0 val sss = iii as String // ダメー val sss = iii as String? // ダメー val sss = null as String? // null println(sss)
"Safe" (nullable) cast operator
失敗の時はnullが返る。まあ使うならこっちかな?
val iii = 0 val sss: String? = iii as? String // null println(sss)
Declaration-site variance
うーん、あまり知らずにout
使ってたけど、今もようわからなんです。
こういうのはもう少し実践的なコード書かないとあれだなー。
abstract class Momo<out T> { abstract fun momo(): T // outなので引数には使えない // abstract fun momo(mo: T): T } class Mooo : Momo<String>() { override fun momo(): String { return "mooo" } } fun momomomo(momo: Momo<String>) { val mooooooo: CharSequence = momo.momo() println(mooooooo) } momomomo(Mooo())
in
も。
abstract class HunHun<in T> { abstract fun hunhun(hunhun: T): String // inなので戻り値には指定できない // abstract fun hunhun(hunhun: T): T } class Hunga : HunHun<Int>() { override fun hunhun(hunhun: Int): String { return hunhun.toString() } } fun hunhunhun(hunhunhun: HunHun<Int>): String { return hunhunhun.hunhun(10) } println(hunhunhun(Hunga())) // 10
Star-projections
なんでもかかったこいやー!な*
さん。
下の例だと型が決まってないので、Any?になる。
val ints: Array<Int> = arrayOf(1, 2, 3) val nums: Array<*> = ints val jjjjj: Any? = nums.get(0) println(jjjjj)
まとめ
そろそろ何をやったのか忘れそうな雰囲気🙉
2016/12/10の30分 Kotlinメモ🌂
2016/12/10の30分 Kotlinメモ🌂
書いてるコードは雑にここにあります。
Delegated Properties
あー、あーなるほど。ようわからん。
良さそうなんだけど、使い方に慣れなくて全くようわからん状態のコードを書いてた。
open class User(open val name: String) { var age = 0 var gender: Int = 0 set(value) { field = value } val isAdmin: Boolean get() = false val language by Language() } class Language { val code = 1 operator fun getValue(thisRef: Any?, property: KProperty<*>): Language { return Language() } } val u3 = User("test") println(u3.language.code)
なるほど、すべてりかいした(嘘
DroidKaigiの締め切り日が迫ってるってコードをなんとかDelegated Propertiesとか使っちゃって書こうとしたけど、無理無理
class DroidKaigi(val now: LocalDateTime) { var status: String by Shimekiri(now) } class Shimekiri(val now: LocalDateTime) { val kaisai = LocalDate.of(2016, 3, 9).atTime(0, 0) var status: String = "やばい" operator fun setValue(droidKaigi: DroidKaigi, property: KProperty<*>, s: String) { } operator fun getValue(droidKaigi: DroidKaigi, property: KProperty<*>): String { return status } }
とりあえずlazy
が良さ気なことは理解した。
modeで色々変えられるっぽい。デフォルトはSynchronizedLazyImplだね。
public fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer) public fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> = when (mode) { LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer) LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer) LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer) }
まとめ
今日ついに上着買いました🎉
まだ着ないけど...
Tupleライブラリ GuildのKotlin版作ってみた - 2016/12/09の30分 Kotlinメモ💪
2016/12/09の30分 Kotlinメモ💪
まあ30分以上やってるけどねー
今日はRetty Tech Cafe #8で「Kotlinでマッチョする話」というテーマで話すので、それのネタ仕込み。
Guild Kotlin
GuildというJavaでTupleを作るライブラリを作っていて、それのKotlin版を作ってみた。
ブログに書いた「4つと5つ値を持つTupleを作ってみた」 + 「PairからTripleを作る拡張関数を書いてみた」の集大成。
A to B to C
という感じでto
つなぎでTriple
を作ったり、A to B to C to D
で4つの値を持つTuple Quartet
を作ったりできるライブラリになってる。
Quartet
の実装は以下のようになってる。
package com.os.operando.guild /** * A tuple of four elements. * * @param F first element type * @param S second element type * @param T third element type * @param FO fourth element type * @property first First value * @property second Second value * @property third Third value * @property fourth Fourth value */ class Quartet<out F, out S, out T, out FO>( val first: F, val second: S, val third: T, val fourth: FO) { override fun toString(): String { return "Quartet(first=$first, second=$second, third=$third, fourth=$fourth)" } companion object { @JvmStatic fun <F, S, T, FO> create(first: F, second: S, third: T, fourth: FO): Quartet<F, S, T, FO> { return Quartet(first, second, third, fourth) } } } infix fun <A, B, C, D, E> Quartet<A, B, C, D>.to(that: E): Quintet<A, B, C, D, E> = Quintet(this.first, this.second, this.third, this.fourth, that)
Javaから使われることを考えてcompanion objectでcreateメソッド書いてみたけど、Java版 Guildがあるから、いらねーなこれって気づいた。
後々消す。
infix
でゴニョゴニョ書いてるのは、to
つなぎでQuartet
から5つの値を持つ Tuple Quintet
を作る拡張関数でやすん。
このto
つなぎでTuple生成するの気に入ってます。
Sample
Guild Kotlinは以下のような感じで使える。便利ー💪💪💪💪💪
package com.os.operando.guild.sample import com.os.operando.guild.to import java.time.LocalDateTime fun main(args: Array<String>) { val triple = 1 to 10L to "triple" println(triple.first) println(triple.second) println(triple.third) val quartet = 1 to 10L to true to "quartet" println(quartet.first) println(quartet.second) println(quartet.third) println(quartet.fourth) val quintet = 1 to 10L to true to LocalDateTime.now() to "quintet" println(quintet.first) println(quintet.second) println(quintet.third) println(quintet.fourth) println(quintet.five) }
後々jCenterに公開する。
group idとかどうしようかなーとかあって、まあ後々ちゃんとそこら辺色んなライブラリを参考にして公開する。
まとめ
資料作らないと...