Kotlin _4

### ジェネリクス
型を汎用化する
class使用時にデータ型を指定する

class MyData<T> {
    fun getThree(x: T){
        println(x)
        println(x)
        println(x)
    }
}

fun main(args: Array<String>) {
	val mi = MyData<Int>()
    mi.getThree(55)
}

### data class

data class Point(val x: Int, val y: Int)

fun main(args: Array<String>) {
	val p1 = Point(3, 5)
    val p2 = Point(3, 5)
    
    println(p1)
    println(if (p1 == p2) "same" else "not same")
}

### Collection
List: 順番を持つデータの集合(Immutable/Mutable)、Set: 順番を持たない|重複を許さないデータの集合(Immutable/Mutable)、Mapはkeyと値でデータを管理(Immutable/Mutable)
– Immutableなデータを作る
– listはlistOfで使う。変更する場合は、mutableListOfで使用する

fun main(args: Array<String>) {
	val sales: List<Int> = listOf(20, 30, 40)
    println(sales[1])
}

– setはsetOf
– 変更する場合は、mutableSetOfで使用する

fun main(args: Array<String>) {
	val answers: Set<Int> = setOf(5, 3, 8, 5)
    println(answers)
    println(answers.contains(3))
    
    val set1 = setOf(1, 3, 4, 8)
    val set2 = setOf(3, 5, 7, 9)
    println(set1.intersect(set2))
    println(set1.union(set2))
}

– mapはmapOf
– mutableMap

fun main(args: Array<String>) {
	val users: Map<String, Int> = mapOf("yamada" to 10, "tanaka" to 20, "sato" to 30)
    println(users["yamada"])
    println(users.size)
	println(users.keys)
    println(users.values)
    println(users.entries)
}

### map
コレクションを処理するための命令にmap, filter, forEachなどが使える

fun main(args: Array<String>) {
	val prices = listOf(53.2, 48.2, 32.8)
    prices
    	.map{ n -> n * 1.08} // 引数 ->処理
        .filter { n -> n > 50}
        .forEach { println(it)}
}

### 例外処理
try & catch

class MyException(message: String): Throwable(message){
    
}

fun div(a: Int, b: Int){
    try {
        if(b < 0){
            throw MyException("not minus!")
        }
        println(a / b)
    } catch(e: ArithmeticException){
        println(e.message)
    }
}

fun main(args: Array<String>) {
	div(3, 0)
}

### Nullable
nullになりそうな型は、型の後ろに「?」を付ける

fun main(args: Array<String>) {
	val s: String = null
    println(s)
}

Null can not be a value of a non-null type String

fun main(args: Array<String>) {
	val s: String? = null
    println(s)
    
    if(s != null){
        println(s.length)
    } else {
        println(null)
    }
}

Kotlin _3

### class

class User {
    var name = "Me!"
    fun sayHi(){
        println("hi $name")
    }
}

fun main(args: Array<String>){
	val user = User()
    println(user.name)
    user.sayHi()
    
    user.name = "steve"
    println(user.name)
    user.sayHi()  
}

constructor
->classの引数の渡し方はmethodと同様に型を指定する

class User(var name: String) { // constructor
    var team = "red"
    init {
        println("instance created: name: $name, team: $team")
    }
    fun sayHi(){
        println("hi $name")
    }
}

fun main(args: Array<String>){
	val tom = User("tom")
    println(tom.name)
    tom.sayHi()
}

instance created: name: tom, team: red
tom
hi tom

### getter, setter

    // getter
//     get(){
//         return field.toUpperCase()
//     }
    get() = field.toUpperCase()
    // setter
    set(value) {
        if(value != ""){
            field = value
        }
    }

### override
継承される側はopenを付ける

class AdminUser(name: String): User(name){
    fun sayHello(){
        println("hello $name")
    }
    override fun sayHi(){
        println("[admin] hi $name")
    }
    
}

open class User(var name: String){
    open fun sayHi(){
        println("hi $name")
    }
}

fun main(args: Array<String>) {
    val bob = AdminUser("bob")
    println(bob.name)
    bob.sayHello()
    bob.sayHi()
}

### アクセス修飾子
public:どこからでも、protected: そのクラス+サブクラス、private:そのクラスのみ
-> アクセスをcontrollすることで安全なプログラムを書ける

### 拡張

fun User.sayHi(){
    println("[ext] hello $name")
}

val User.myName: String
 get() = "I am $name"

open class User(var name: String){
    fun sayHi(){
        println("hi $name")
    }
}

fun main(args: Array<String>) {
    val bob = User("bob")
    println(bob.name)
    bob.sayHi()
}

### 抽象クラス・具象クラス
抽象クラスはabstractとする

abstract class User{
    abstract fun sayHi()
}

class Japanese: User() {
    override fun sayHi(){
        println("こんにちは!")
    }
}

class American: User() {
    override fun sayHi(){
        println("Hi!")
    }
}


fun main(args: Array<String>) {
	val tom = American()
    val aki = Japanese()
    tom.sayHi()
    aki.sayHi()
}

### Interface
抽象プロパティ、抽象メソッド、メソッド

interface Sharable {
    val version: Double
    fun share()
    fun getInfo(){
        println("Share I/F ($version)")
    }
}

class User: Sharable {
    override val version = 1.1
    override fun share(){
        println("Sharing ...")
    }
}

fun main(args: Array<String>) {
	val user = User()
    user.share()
    user.getInfo()
}

Kotlin _2

### 演算

fun main(args: Array<String>){
	// + - * / %
	val x = 10
    println(x / 3)
    println(x / 3.0)
    println(x % 3.0)
    
    var y = 5
    y++
    println(y)
    y--
    println(y)
    
    var z = 4
    z += 12
    
    // AND &&, or ||, Not !
    val flag = true
    println(!flag)
}

3
3.3333333333333335
1.0
6
5
false

### 文字列

fun main(args: Array<String>){
	// 文字列
	println("hello " + "world")
    
    val name = "yamada"
	println("my name is $name")
    println("my score is ${15 + 33}")
    
    // \n:改行 \t:タブ
    println("hello\n wor\tld")
}

hello world
my name is yamada
my score is 48
hello
wor ld

### ifの条件分岐

val score = 85
    if(score > 80){
        println("great!")
    } else if(score > 60){
        println("ok")
    } else {
        println("soso ..")
    }

> >= < <= == != 三項演算子 [code] val result = if(score> 80) “great” else “soso”
println(result)
[/code]

### when

// when
	val num = 3
    when(num) {
        0 -> println("Zero")
        1 -> println("One")
        2, 3 -> println("Two or Three")
        in 4..10 -> println("Many")
        else -> println("other")
    }

### while

var i = 0
    while (i < 10){
        println("loop: $i")
        i++
    }

do {
        println("loop2: $i")
        i++
    } while(i < 5)
&#91;/code&#93;

### for
&#91;code&#93;
for (i in 0..9){
        if(i == 5) break
        println(i)
    }

for (i in 0..9){
        if(i == 5) continue
        println(i)
    }
&#91;/code&#93;

### 関数
関数の引数は型を指定する
&#91;code&#93;
fun sayHi(name: String = "John", age: Int = 23){
    println("hi! $name($age)")
}

fun main(args: Array<String>){
	// for (変数)
    sayHi("tom", 22)
    sayHi()
}

値を返す時は、関数側で型を指定する

fun sayHi(): String{
    return "hi!"
}

fun main(args: Array<String>){
    val msg = sayHi()
    println(msg)
}

fun sayHi() = "hi!"

-> 配列で返す場合はどうするんだろう??

Kotlin _1

kotlin
ScalaやGroovyなどの言語と同様に、Javaバイトコードにコンパイルされて、JVMで動作する静的型付けのオブジェクト指向
静的なnull安全が保証されている、NullPointerExceptionを防ぐため、@Nullable 型と @NonNull 型が組み込まれている
Javaよりコードが短く簡潔で、Javaのコードを呼び出せる
Uber、Evernote、NetflixなどがKotlinを使用

### 1. Hello World

fun main(args: Array<String>){
    println("Hello world")
}

### 2. 変数

// -val 再代入できない 
// -var 再代入できる
// なるべくvalで宣言し、必要なところのみvarで宣言する

fun main(args: Array<String>){
    val msg: String = "Hello world"
    println(msg)
}

再代入はできない

fun main(args: Array<String>){
    val msg: String = "Hello world"
    println(msg)
    msg = "Hello world 2"
    println(msg)
}

Val cannot be reassigned
再代入の場合はvarを使う

fun main(args: Array<String>){
    var msg: String = "Hello world"
    println(msg)
    msg = "Hello world 2"
    println(msg)
}

### 3. 基本型
Double: 64ビット浮動小数点
Float: 32ビット浮動小数点
Long: 64ビット符号付き整数
Int: 32ビット符号付き整数
Short: 16ビット符号付き整数
Byte: 8ビット符号付き隻数
Char: 1文字を表す文字列
Boolean: 真偽値
String: 文字列

数値定数

val digits = 1234 // 10進数
val longInt = 1234L // Long
val hex = 0x1F // 16進数
val bin = 0b00001011 // 2進数
val dbl = 1234.5 // デフォルトはdouble
val withE = 123.4e10 // 123.4 * 10^10
val flt = 123.4f // Float

文字と文字列

// Char型はシングルクォート
val c = '0'
val n = '\n'
val u = '\uFF00'

// ダブルクォートの文字列も使える
val s = "Hello, world!\n"

val text = """
文字列を記入する。
	インデントもそのまま。
"""

// 文字列の中に変数を埋め込む
val i = 10
val str = "i = $i, i x 2 = ${i * 2}"

// stringはimmutableで構成要素はchar
val c0 = str[0]
for (chr in str){
	println(chr)
}

fun main(args: Array<String>){
    val msg: String = "hello world"
    val c: Char = 'a'
    
    val i: Int = 100
    val l: Long = 55555555555555L
    
    val d: Double = 234.523 
    val f: Float = 12.344F
    
    val flag: Boolean = true 
}

kotolin 文字列の連結

fun changeTextView(view: View){
        var calendar = Calendar.getInstance()
        val hour = calendar.get(Calendar.HOUR_OF_DAY)
        val minute = calendar.get(Calendar.MINUTE)

        messageTextView.text = "Hello android!"
        textView.text = "時間 ${hour.toString()}:${minute.toString()}"
    }

androidで時間を表示する

fun changeTextView(view: View){
        var calendar = Calendar.getInstance()
        val minute = calendar.get(Calendar.MINUTE)

        messageTextView.text = "Hello android!"
        textView.text = minute.toString()
    }

勝手が異なるから、スクリーンショットの転送も最初は一仕事だ。

valは変更不可
varは変更可

Kotlin 構文2

getter, setter

class User(var name: String){
  var team = "red"
  get(){
    return field.toUpperCase()
  }

  set(value){
    if (value !=""){
      field = value
    }
  }

  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.team)
  tom.sayHi()
}

class override

class AdminUser(name: String): User(name){
  fun sayHello(){
    println("hello $name")
  }
  override fun sayHi(){
    println("what $name")
  }
}
open class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = AdminUser("bob")
  println(bob.name)
  bob.sayHi()
}

アクセス修飾子: privateとpublic

open class User(private var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

class extension

fun User.sayHello(){
  println("hello $name")
}

val User.myName: String
 get() = "I am $name"

class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = User("bob")
  bob.sayHello()
  bob.sayHi()
  println(bob.myName)
}

抽象クラス

abstract class User {
  abstract fun sayHi()
}
class Japanese: User(){
  override fun sayHi(){
    println("こんにちは")
  }
}
class American: User(){
  override fun sayHi(){
    println("hi")
  }
}

fun main(args: Array<String>){
  val tom = American()
  val taro = Japanese()
  tom.sayHi()
  taro.sayHi()
}

interface

interface Sharable{
  // 抽象プロパティ、抽象メソッド、メソッド
  val version: Double
  fun share()
  fun getInfo(){
    println("Share I/F ($version)")
  }
}
class User: Sharable {
  override val version = 1.1
  override fun share(){
    println("Sharing..")
  }
}

fun main(args: Array<String>){
 val user = User()
 user.share()
 user.getInfo()
}

generics

class MyData<T> {
  fun getThree(x: T){
    println(x)
    println(x)
    println(x)
  }
}

fun main(args: Array<String>){
  val i = MyData<Int>()
  i.getThree(32)

  val s = MyData<String>()
  s.getThree("hello")
}

データクラス

data class Point(val x: Int, val y: Int)

fun main(args: Array<String>){
  val p1 = Point(3, 5)
  val p2 = Point(3, 5)
  val p3 = p1.copy()

  println(p1)
  println(if (p1 == p2) "same" else "not same")
}

List

fun main(args: Array<String>){
  val sales: List<Int> = listOf(20, 30, 40)
  println(sales[1])
  println(sales.size)
  for (sale in sales){
    println(sale)
  }
}

set

fun main(args: Array<String>){
  val answers: Set<Int> = setOf(3, 5, 8, 3)
  println(answers)
  println(answers.contains(3))

  val set1 = setOf(1, 3, 5, 8)
  val set2 = setOf(3, 5, 8, 9)

  println(set1.intersect(set2))
  println(set1.union(set2))
  println(set1.subtract(set2))
}

Map

fun main(args: Array<String>){
  val users: Map<String, Int> = mapOf("kobayashi" to 10, "kagawa" to 22, "tanaka" to 33)
  println(users["kobayashi"])
  println(users.size)
  println(users.keys)
  println(users.values)
  println(users.entries)
}

map, filter, foreach

fun main(args: Array<String>){
  val prices = listOf(53.2, 48.2, 32.8)
  prices 
   /*.map { n -> n + 1.08} //*/
   .map { it * 1.08 }
   .filter { it > 50 }
   .forEach { println(it) }
}

例外処理

fun div(a: Int, b: Int){
  try {
    println(a / b)
  } catch(e: ArithmeticException) {
   println(e.message)
  }
}

fun main(args: Array<String>){
  div(3, 0)
}

Nullable型

fun main(args: Array<String>){
  val s: String? = null
  /*println(s)*/

  /*if (s != null){
    println(s.length)
  } else {
    println(null)
  }*/
  println(s?.length ?: -1)
}

Kotlin 構文1

変数

fun main(args: Array<String>){
  val msg: String = "Hello World"
  println(msg)
}

データ型

  val msg: String = "Hello World"
  val c: Char = 'a'
  val i: Int = 100
  val l: Long = 555555555555L
  val d: Double = 234.352
  val f: Float = 123.345
  val flag: Boolean = true

データ演算

val x = 10
  println(x / 3)
  println(x / 3.0)
  println(x % 3)
  var y = 5
  y++
  y--
  println(y)
  var z = 4
  z += 12
  println(z)
  val flag = true
  println(!flag)

文字列

  println("hello " + "world")

  val name = "yoshimoto"
  println("my name is $name")
  println("my score is ${12 + 43}")

  println("hello\n worl\td")

ifの条件分岐

val score = 85
  if (score > 80){
    println("Great!")
  } elseif (score > 60){
      println("good!")
  } else {
    println("soso ..")
  }

when 条件分岐

val num = 3
  when (num){
    0 -> println("zero")
    1 -> println("one")
    in 4.. 10 -> println("many")
    else -> println("other")
  }

while, for

var i = 0
  while (i < 10){
    println("loop: $i")
    i++
  }
for (i in 0..9){
    println(i)
  }

関数

fun sayHi(name: String = "tebes", age: Int = 23){
  println("hi! $name ($age)")
}

fun main(args: Array<String>){
  sayHi("tom", 22)
  sayHi()
}

関数の返り値

fun sayHi(): String {
  return "hi!"
}

fun main(args: Array<String>){
  val msg = sayHi()
  println(msg)
}

class

class User {
  var name = "me!"
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val user = User() // インスタンス
  println(user.name)
  user.sayHi()
}

コンストラクタ引数

class User(var name: String) { //コンストラクタ引数
  /*var name = name*/
  var team = "red"
  init {
    println("instance created: name: $name, team: $team")
  }
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.name)
  tom.sayHi()
}

Kotlin install

JetBrain社が作った、Javaを簡潔に書けるようにした言語です。JVM、Androidで動くことから、Android開発で人気を博しています。

Kotlin

エディタにKotlinのSyntaxを入れます。
kotol

インストールは公式サイトのGettingStarted->Working with the CommandlineよりSDKMAN!をインストールします。

[vagrant@localhost ~]$ curl -s https://get.sdkman.io | bash
[vagrant@localhost ~]$ source "/home/vagrant/.sdkman/bin/sdkman-init.sh"
[vagrant@localhost ~]$ cd kotlin
[vagrant@localhost kotlin]$ sdk version
==== BROADCAST =================================================================
* 15/11/16: Kotlin 1.0.5-2 released on SDKMAN! #kotlin
* 14/11/16: Gradle 3.2 released on SDKMAN! #gradle
* 10/11/16: Grails 3.2.3 released on SDKMAN! #grailsfw
================================================================================
SDKMAN 5.1.7+91
[vagrant@localhost kotlin]$ sdk install kotlin

インストールが終了したら、動作確認しましょう。

[vagrant@localhost kotlin]$ kotlin -version
Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
[vagrant@localhost kotlin]$ kotlinc
Welcome to Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
Type :help for help, :quit for quit
>>> 1 + 2
3
fun main(args: Array<String>){
  println("Hello World")
}
[vagrant@localhost kotlin]$ kotlinc myapp.kt -include-runtime -d myapp.jar
[vagrant@localhost kotlin]$ ls
myapp.jar  myapp.kt
[vagrant@localhost kotlin]$ java -jar myapp.jar
Hello World