Open29

Kotlin 1.1 release

Coroutines

Type aliases

A type alias allows you to define an alternative name for an existing type.

既存の型にエイリアス名を付与できるようになった

  • ジェネリクス型
  • 関数の型
    で活用することを想定している模様
fun main(args: Array<String>) {
    println("Hello World!")

    val data = mapOf(
        Pair("ジョコビッチ", 1),
        Pair("メドベージェフ", 2),
        Pair("ズベレフ", 3),
        )

    println(showNoOne(data))
}

typealias ATPRanking = Map<String, Int>
// 元の型とaliasの型は互いに同じ型とみなされる模様(型安全というよりは名前つけて読みやすくできるって感じなのかな?)
fun showTop(rankingData: ATPRanking) = rankingData.minByOrNull{ it.value}?.key
fun showNoOne(rankingData: Map<String, Int>) = showTop(rankingData)

※新しい型を生成しているわけではない=>よって元の型とエイリアスは相互に入れ替え可能

使用例

  • Null許容型に名前を付ける
class TeamMember(val name: String)
typealias MaybeTeamMember = TeamMember?
  • ジェネリクスにわかりやすい名称を
class Container<T>(var item: T) {
}

typealias StringContainer = Container<String>

typealiasはトップレベルにしか宣言できない模様

可視性修飾子としてpublic/internal/privateが利用可能

Bound callable references

You can now use the :: operator to get a member reference pointing to a method or property of a specific object instance.

メンバの参照(メソッド・プロパティ)に::オペレータが使えるようになった

fun PlayerIntroduce() {
    val player = Player("ジョコビッチ", "セルビア")
    println(player::name)
    println(player::introduce)
}

class Player(val name: String, private val country: String) {
    fun introduce(): String {
        return "$name:$country"
    }
}

Sealed and data classes

you can define subclasses of a top-level sealed class on the top level in the same file

SealedクラスのサブクラスをSealedクラスの内部クラスとしてではなく、同一ファイル内であれば定義できるようになった

// トップレベルに宣言
sealed class Leaf
// 同一ファイル内であればOK
data class StringLeaf(val data: String): Leaf()
data class NumberLeaf(val data: Int): Leaf()

Data classes can now extend other classes.

データクラスが他のクラスを拡張可能になった

sealed class LeafSealed
enum class LeafEnum
open class LeafNormal
object LeafObject
interface LeafInterface

data class LeafSealedImpl(val data: Any): LeafSealed() // Sealedはそもそも拡張を前提にしてるのかな?
//data class LeafEnumImpl(val data: Any): LeafEnum() // Enumはそもそも拡張不可
data class LeafNormalImpl(val data: Any): LeafNormal() // open・abstractであれば通常クラスと同様OK
//data class LeafObjectImpl(val data: Any): LeafObject() // objectはそもそも拡張不可
data class LeafInterfaceImpl(val data: Any): LeafInterface // interfaceもOK

Destructuring in lambdas

ラムダ式で直接分解宣言が使えるようになった

Underscores for unused parameters

使わない変数を_で受け取れるようになった(分解宣言時等に使える)

mapOf(Pair("A", 0)).forEach { (_, _) -> println("wow!!")}

Underscores in numeric literals

val oneMillion = 1_000_000

Shorter syntax for properties

カスタムプロパティの型が省略できるようになった

data class Person(val name: String, val age: Int) {
    val isAdult get() = age >= 20
}

Inline property accessors

プロパティへのカスタムアクセッサーもinline関数化できるようになった

Local delegated properties

ローカル変数にもdelegateプロパティが使えるようになった
※実アクセスのタイミングまで遅延評価できるようになったってことか?

Interception of delegated property binding

Generic enum value access

Enumのジェネリクス値を参照できるようになった?

inline fun <reified T : Enum<T>> printAllValues() {
    print(enumValues<T>().joinToString { it.name })
}

Scope control for implicit receivers in DSLs

rem operator

mod(非推奨) → rem

String to number conversions

変換時に数値でない場合にNullを返してくれるAPIが増えた

String.toIntOrNull(): Int?

onEach()

forEach()は出力がないが入力されたiterableをそのまま出力しつつ処理をできるonEach()APIが増えた

also(), takeIf(), and takeUnless()

  • also

オブジェクトの生成と同時についでに何かしたいみたいな時に使う?

  • takeIf
  • takeUnless

It checks whether the receiver meets the predicate, and returns the receiver, if it does or null if it doesn't.

単一の値に対するfilterのようなもので条件を満たさない場合はNullが返る
エルビス演算子と合わせて使うといいみたい

takeIf => trueの場合レシーバが返る
takeUnless => falseの場合レシーバが返る

[スコープ関数]

https://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e

groupingBy()

条件に応じた集計をしやすくするAPIかな

val frequencies = words.groupingBy { it.first() }.eachCount()

Map.toMap() and Map.toMutableMap()

Map用のコピーメソッドAPI

Map.minus(key)

まぁremoveのイミュータブル版みたいな感じかな

minOf() and maxOf()

複数のComparableの実装クラスに対して比較ができるAPI(comparatorの指定も可能)

Array-like List instantiation functions

配列見たいにリスト初期化できるAPI作ったよ => たぶん使わない気がする

val list = MutableList(10) { 0 }

Map.getValue()

val map = mapOf("key" to 42)
val mapWithDefault = map.withDefault { k -> k.length }
val value2 = mapWithDefault.getValue("key2") // 通常ExceptionだwithDefaultで定義されたデフォルト値が返るようになった

Abstract collections

独自コレクションを実装しやすくしてくれるAbstractCollection<T>が追加された模様

Array manipulation functions

Arrayの中身表示するいい感じのAPI増えましたよ

val array = arrayOf(arrayOf("a1", "a2"), "b", "c")
println(array.toString())                        // [Ljava.io.Serializable;@378bf509
println(array.contentToString())                 // [[Ljava.lang.String;@5fd0d5ae, b, c]
println(array.contentHashCode())                 // -1359830322
println(array.contentDeepToString())             // [[a1, a2], b, c]
println(array.contentDeepHashCode())             // 94935522
ログインするとコメントできます