几分钟内学会Kotlin语言
17-05-19
banq
谷歌宣布kotlin成安卓开发一级语言以后,kotlin大热,Kotlin是JVM上的静态类型的编程语言,它是100%兼容的java。
废话少说,上代码,由于代码太长,分两段:
废话少说,上代码,由于代码太长,分两段:
//这是单行注释 // /* 这是多行注释 */ // 这和Java的 "package" 差不多. package com.learnxinyminutes.kotlin /* Kotlin程序入口函数是名为"main". 这个函数的入参是包含命令行参数的数组 */ fun main(args: Array<String>) { /* 声明值是使用"var" 或 "val". "val"是一旦分配值后就不能变,不变量,相反"vars" 是声明变量 */ val fooVal = 10 // 之后就不能再给fooVal分配其他值了 var fooVar = 10 fooVar = 20 // fooVar是变量,能够再次分配值 /* 大多数情况, Kotlin能够决定一个变量的类型是什么。 这样我们不必显式明确每次去指定变量类型了。 我们可以通过如下方式明确定义变量类型: */ val foo : Int = 7 /* Kotlin包含两种类型的字符串:与Java字符串相同的escaped strings和新的raw strings, escaped strings中的换行符是\n字符串和Java中一样定义, 反斜杠是换行符 */ val fooString = "My String Is Here!" val barString = "Printing on a new line?\nNo Problem!" val bazString = "Do you want to add a tab?\tNo Problem!" println(fooString) println(barString) println(bazString) /* 行字符串(raw strings)由三个引号分隔 ("""). 顾名思义能包含新的一行和其他任何字符。 下面是给fooRawString赋值的是一个函数helloWorld,直至第四行的三个引号才表示赋值结束 */ val fooRawString = """ fun helloWorld(val name : String) { println("Hello, world!") } """ println(fooRawString) /* 字符串能保护模板表达式 模板表达式是以美元符号开始($). */ val fooTemplateString = "$fooString has ${fooString.length} characters" println(fooTemplateString) /* 对于一个变量是空必须明确指定其是nullable. 变量可以在其类型后面追加问号?指定其是nullable, 然后使用?.操作符访问这个nullable的变量 也可以使用?: 操作符在其为null时为其分配一种值。 */ var fooNullable: String? = "abc" println(fooNullable?.length) // => 3 println(fooNullable?.length ?: -1) // => 3 fooNullable = null println(fooNullable?.length) // => null println(fooNullable?.length ?: -1) // => -1 /* 函数是使用"fun" 定义 函数参数在函数名后面的括号中指定。函数参数可以有默认值。如果需要,函数返回类型在参数之后指定。 */ fun hello(name: String = "world"): String { return "Hello, $name!" } println(hello("foo")) // => Hello, foo! println(hello(name = "bar")) // => Hello, bar! println(hello()) // => Hello, world! /* 一个函数参数可以使用"vararg" 标注, 能够让许多参数传递进入函数。 */ fun varargExample(vararg names: Int) { println("Argument has ${names.size} elements") } varargExample() // => Argument has 0 elements varargExample(1) // => Argument has 1 elements varargExample(1, 2, 3) // => Argument has 3 elements /* 当一个函数由单个表达式组成时,那么这个卷括号可以被省略。函数内容体是在等于号=之后指定。 */ fun odd(x: Int): Boolean = x % 2 == 1 println(odd(6)) // => false println(odd(7)) // => true // 如果返回类型能被推断,我们就不必指定了。 fun even(x: Int) = x % 2 == 0 println(even(6)) // => true println(even(7)) // => false // 函数能用函数作为参数,返回页首函数。 fun not(f: (Int) -> Boolean): (Int) -> Boolean { return {n -> !f.invoke(n)} } // Named函数能使用 :: 作为参数指定. val notOdd = not(::odd) val notEven = not(::even) // Lambda 表达式能指定为参数 val notZero = not {n -> n == 0} /* 如果一个lambda仅有一个参数,它的声明可以被忽视(随着 ->一起). 单个参数名将是"it". */ val notPositive = not {it > 0} for (i in 0..4) { println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") } // "class" 是用来声明类 class ExampleClass(val x: Int) { fun memberFunction(y: Int): Int { return x + y } infix fun infixMemberFunction(y: Int): Int { return x * y } } /* 创建新的实例使用构造器 Kotlin没有 "new" */ val fooExampleClass = ExampleClass(7) // 成员函数能使用点符号调用 println(fooExampleClass.memberFunction(4)) // => 11 /* 如果一个函数被"infix"标注,能使用infix notation调用 下面fooExampleClass infixMemberFunction 4等同于 fooExampleClass.memberFunction(4) */ println(fooExampleClass infixMemberFunction 4) // => 28 /* 数据类是创建只包含数据的精确方式. "hashCode"/"equals" 和 "toString" 等方法会自动产生。 */ data class DataClassExample (val x: Int, val y: Int, val z: Int) val fooData = DataClassExample(1, 2, 4) println(fooData) // => DataClassExample(x=1, y=2, z=4) // 数据类没有 "copy" 函数 val fooCopy = fooData.copy(y = 100) println(fooCopy) // => DataClassExample(x=1, y=100, z=4) // 对象能被解构入多个变量。 val (a, b, c) = fooCopy println("$a $b $c") // => 1 100 4 // 解构 "for" 循环 for ((a, b, c) in listOf(fooData)) { println("$a $b $c") // => 1 100 4 } val mapData = mapOf("a" to 1, "b" to 2) // Map.Entry 也能解构 for ((key, value) in mapData) { println("$key -> $value") } // "with" 函数类似JavaScript "with" 语句. data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) val fooMutableData = MutableDataClassExample(7, 4, 9) with (fooMutableData) { x -= 2 y += 2 z-- } println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) /* 使用 "listOf" 函数创建集合 集合是不可变的,元素不能增加和移走 */ val fooList = listOf("a", "b", "c") println(fooList.size) // => 3 println(fooList.first()) // => a println(fooList.last()) // => c // list元素可通过索引访问。 println(fooList[1]) // => b // 一个可变的 list能使用 "mutableListOf" 函数创建 val fooMutableList = mutableListOf("a", "b", "c") fooMutableList.add("d") println(fooMutableList.last()) // => d println(fooMutableList.size) // => 4 // 使用 "setOf" 创建set val fooSet = setOf("a", "b", "c") println(fooSet.contains("a")) // => true println(fooSet.contains("z")) // => false // 使用 "mapOf" f创建map val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) // Map values can be accessed by their key. println(fooMap["a"]) // => 8 //待续 <p class="indent"> |
banq
2017-05-19 21:24
/* 使用 "generateSequence" f函数创建序列号,它是懒赋值的集合,只有使用时才真正赋值。 */ val fooSequence = generateSequence(1, { it + 1 }) val x = fooSequence.take(10).toList() println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 产生 斐波纳契案例 fun fibonacciSequence(): Sequence<Long> { var a = 0L var b = 1L fun next(): Long { val result = a + b a = b b = result return a } return generateSequence(::next) } val y = fibonacciSequence().take(10).toList() println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] // Kotlin提供colletion的高阶函数。 val z = (1..9).map {it * 3} .filter {it < 20} .groupBy {it % 2 == 0} .mapKeys {if (it.key) "even" else "odd"} println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} // "for" 循环 for (c in "hello") { println(c) } // "while" 循环是和其他语言一样 var ctr = 0 while (ctr < 5) { println(ctr) ctr++ } do { println(ctr) ctr++ } while (ctr < 10) /* "if" 能表达返回一个值的表达式 */ val num = 5 val message = if (num % 2 == 0) "even" else "odd" println("$num is $message") // => 5 is odd // "when" 能作为"if-else if" 替换 val i = 10 when { i < 7 -> println("first block") fooString.startsWith("hello") -> println("second block") else -> println("else block") } // "when" 能带一个参数 when (i) { 0, 21 -> println("0 or 21") in 1..20 -> println("in the range 1 to 20") else -> println("none of the above") } // "when" 能用在返回一个值的函数can be used as a function that returns a value. var result = when (i) { 0, 21 -> "0 or 21" in 1..20 -> "in the range 1 to 20" else -> "none of the above" } println(result) /* 使用"is" 操作符检查类型,如果一个对象传入类型检查,就无需再次明确casting 它了 */ fun smartCastExample(x: Any) : Boolean { if (x is Boolean) { // x is automatically cast to Boolean return x } else if (x is Int) { // x is automatically cast to Int return x > 0 } else if (x is String) { // x is automatically cast to String return x.isNotEmpty() } else { return false } } println(smartCastExample("Hello, world!")) // => true println(smartCastExample("")) // => false println(smartCastExample(5)) // => true println(smartCastExample(0)) // => false println(smartCastExample(true)) // => true // Smartcast also works with when block fun smartCastWhenExample(x: Any) = when (x) { is Boolean -> x is Int -> x > 0 is String -> x.isNotEmpty() else -> false } /* Extensions是一个增加新函数到类的方式,类似 C# extension 方法 */ fun String.remove(c: Char): String { return this.filter {it != c} } println("Hello, world!".remove('l')) // => Heo, word! println(EnumExample.A) // => A println(ObjectExample.hello()) // => hello } // Enum类似Java enum类型 enum class EnumExample { A, B, C } /* "object"能被用于创建单例对象,不能初始化它,但是能使用名称引向它。类似 Scala singleton objects. */ object ObjectExample { fun hello(): String { return "hello" } } fun useObject() { ObjectExample.hello() val someRef: Any = ObjectExample // we use objects name just as is } <p class="indent"> |