美文网首页
20170608_kotlin入门_part1

20170608_kotlin入门_part1

作者: mingmingz | 来源:发表于2017-07-15 21:22 被阅读0次

本来嘛在IDEA的KotlinEDU已经完成一大半的入门小测试了,但换了电脑,IDEA更新成2017的后,发现KotlinEDU好像只支持2016版的,无奈,而且导入koans会有maven引起的错误,我又不会解决,只好在网页版的来了,既然要重头来,那就记录记录咯?反正加强印象

我们从Examples看起(如果看过kotlin官方文档那这些Example看起来会更容易,当然如果没看过我觉得还是能看得懂的)

HelloWorld

先从提供的例子入手了解一下基础语法吧

1.Simplest version

最简单的莫过于输出一个HelloWorld

/**
 * We declare a package-level function main which returns Unit and takes
 * an Array of strings as a parameter. Note that semicolons are optional.
 */

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

从注释开始看,这里提到我们声明的方法是包级别的,返回的类型是Unit,使用的参数是一个string数组,而且!分号是可有可无的

这里和Java有什么对比呢?

1.没有类,可以直接声明一个方法,这个方法就是包级别的

2.有默认返回值---Unit,不像java中的没返回值是void,关于Unit我们在后面再慢慢了解

3.println直接以行的形式打印,比System.out.println简洁多了

2.Reading a name from the command line

/**
 * Line 13 demonstrates string templates and array access.
 * See this pages for details:
 * http://kotlinlang.org/docs/reference/basic-types.html#strings
 * http://kotlinlang.org/docs/reference/basic-types.html#arrays
 */

fun main(args: Array<String>) {
    if (args.size == 0) {
        println("Please provide a name as a command-line argument")
        return
    }
    println("Hello, ${args[0]}!")
}

在13行这里输出一个字符串,我们可以以${}的形式直接将一个参数以toString的方式输出

//如果args[0]="zhangsan",那么:
println("Hello, ${args[0]}!")----Hello,zhangsan

//如果有val name="zhangsan",那么:
println("Hello,$name")----Hello,zhangsan

3.Reading many names from the command line

/**
 * Line 2 demonstrates the for-loop, that would have been called "enhanced"
 * if there were any other for-loop in Kotlin.
 * See http://kotlinlang.org/docs/reference/basic-syntax.html#using-a-for-loop
 */

fun main(args: Array<String>) {
    for (name in args)
        println("Hello, $name!")
}

(挺奇怪的,前一个例子中说的第13行是包含注释,这个例子的的第2行又是从非注释开始算)

这个例子展示的是kotlin的增强for循环,args是数组,name是一个形参,这样写就能遍历args输出所有的Hello,Xxx

4.A multi-language Hello

/**
 * In this example, `val`  a declaration of a read-only local variable,
 * that is assigned an pattern matching expression.
 * See http://kotlinlang.org/docs/reference/control-flow.html#when-expression
 */

fun main(args: Array<String>) {
    val language = if (args.size == 0) "EN" else args[0]
    println(when (language) {
        "EN" -> "Hello!"
        "FR" -> "Salut!"
        "IT" -> "Ciao!"
        else -> "Sorry, I can't greet you in $language yet"
    })
}

这个例子中,'val'表示的是一个只读的变量

在kotlin中,有两种变量的声明形式,一个是var,一个是val

val:是一个只读的变量

var:是一个可读可写的变量

好玩的还在后头,println里面居然可以不传字符串而是写了一个表达式,还是一个在java里没见过的表达式,理解倒是挺好理解的:

将获取的language进行判断,当其匹配上下面的字段时,则输出对应的字符串,否则就给个友好提示

when表达式是java中switch的进化版,switch的写法还是比较死板的,对我来说when更简洁明了(但初用起来还是有点不适应,除了简单的如例子中匹配上字符串,还能和别的表达式一起用)

5.An object-oriented Hello

/**
 * Here we have a class with a primary constructor and a member function.
 * Note that there's no `new` keyword used to create an object.
 * See http://kotlinlang.org/docs/reference/classes.html#classes
 */

class Greeter(val name: String) {
    fun greet() {
        println("Hello, ${name}");
    }
}

fun main(args: Array<String>) {
    Greeter(args[0]).greet()
}

在这个例子中,我们有一个类带着主构造函数和一个成员方法,我们是不需要用'new'关键字去创建一个对象的!

在这第五个例子中终于见到对象了,在kotlin中创建类的写法和java中也是不同的;

在kotlin里构造函数可以直接跟在类名后面的小括号里,并且这个跟在类名后的小括号中的是主构造函数(对的,有主就有次,还有次级构造,但这里没提到就后面遇到再说)

该类中除了一个主构造函数,还有个成员方法,在成员方法中也是可以直接使用该类的成员变量的(在kotlin中是不是应该用成员变量这个说法?如果有错以后知道了再改正)

Basic syntax walk-through

Use a conditional expression

/**
 * `if` is an expression, i.e. it returns a value.
 * Therefore there is no ternary operator (condition ? then : else),
 * because ordinary `if` works fine in this role.
 * See http://kotlinlang.org/docs/reference/control-flow.html#if-expression
 */
fun main(args: Array<String>) {
    println(max(args[0].toInt(), args[1].toInt()))
}

fun max(a: Int, b: Int) = if (a > b) a else b

if是一个表达式,所以它能返回一个值,他在这里可以很好的充当一个三元运算符的角色

这个例子中展示了一个方法可以在其后面用'='号拼接一个表达式,不需要用到大括号,相当于说我用if判断完,如果成立则返回前一个值,else则返回后一个值

Null-checks

/**
 * A reference must be explicitly marked as nullable to be able hold a null.
 * See http://kotlinlang.org/docs/reference/null-safety.html#null-safety
 */
package 


// Return null if str does not hold a number
fun parseInt(str: String): Int? {
    try {
        return str.toInt()
    } catch (e: NumberFormatException) {
        println("One of the arguments isn't Int")
    }
    return null
}

fun main(args: Array<String>) {
    if (args.size < 2) {
        println("No number supplied");
    } else {
        val x = parseInt(args[0])
        val y = parseInt(args[1])

        // We cannot say 'x * y' now because they may hold nulls
        if (x != null && y != null) {
            print(x * y) // Now we can
        } else {
            println("One of the arguments is null")
    }
    }
}

null检查也是kotlin区别于java最大的特点了,在kotlin中,一个变量必须明确的被标记为可以为null那它才能够为null

我们先看一眼parseInt方法:

// Return null if str does not hold a number
fun parseInt(str: String): Int? {
    try {
        return str.toInt()
    } catch (e: NumberFormatException) {
        println("One of the arguments isn't Int")
    }
    return null
}

在方法声明上,我们指定返回值为Int时,还在Int后面跟了一个'?'号,在这里,'?'号表示的是我这个parseInt方法,它的返回值可以是Int也可以是null

再继续看方法体,在kotlin中自带的基本类型扩展方法很帅,比如上面的str.toInt(),非常确切的面向对象方法,将一个str转换成Int,对,这是kotlin的各种基本类型自带的方法,大家可以玩玩看

在出异常的情况下,我们就返回一个null(说起来kotlin没有编译时异常检查,我觉得这个很不舒服,出异常的机会那么多,让开发者自己来try catch多累啊)

看完parseInt接着看main函数中的内容:

fun main(args: Array<String>) {
    if (args.size < 2) {
        println("No number supplied");
    } else {
        val x = parseInt(args[0])
        val y = parseInt(args[1])

        // We cannot say 'x * y' now because they may hold nulls
        if (x != null && y != null) {
            print(x * y) // Now we can
        } else {
            println("One of the arguments is null")
    }
    }
}

我们在第5第6行可以看到通过parseInt方法我们获取到了x和y,这里获得的是一个可能为null的值

所以在下面想调用的话,编译器强制要求我们判断它两是否为null,为啥呢?因为他们可能为null呀

is-checks and smart casts

/**
  * The `is` operator checks if an expression is an instance of a type and more.
  * If we is-checked an immutable local variable or property, there's no need
  * to cast it explicitly to the is-checked type.
  * See this pages for details:
  * http://kotlinlang.org/docs/reference/classes.html#classes-and-inheritance
  * http://kotlinlang.org/docs/reference/typecasts.html#smart-casts
 */
fun main(args: Array<String>) {
    println(getStringLength("aaa"))
    println(getStringLength(1))
}

fun getStringLength(obj: Any): Int? {
    if (obj is String)
        return obj.length // no cast to String is needed
    return null
}

'is'操作符能用来检查一个表达式是否是一个类型的实例;

如果我们通过'is'来检查一个不可变的变量或属性,那么我们就不需要去明确的将其转换成检查的类型(对的,kotlin会智能转换的);

例如例子里的getStringLength方法,传入了Any类型的对象(kotlin里没有Object类,最上层的类好像是Any)

我们在方法中判断它是否是String,如果是的话,不需要进行一个明确的类型转换声明,kotlin已经知道它是String了,我们就可以直接return 它的length

Use a while-loop

/**
 * `while` and `do..while` work as usual.
 * See http://kotlinlang.org/docs/reference/control-flow.html#while-loops
 */
fun main(args: Array<String>) {
    var i = 0
    while (i < args.size)
        println(args[i++])
}

官方表示:kotlin里的while和do..while和java没啥区别,不多说

Use a for-loop

/**
 * For loop iterates through anything that provides an iterator.
 * See http://kotlinlang.org/docs/reference/control-flow.html#for-loops
 */
fun main(args: Array<String>) {
    for (arg in args)
        println(arg)

    // or
    println()
    for (i in args.indices)
        println(args[i])
}

for循环能迭代任何可以提供迭代器的东西

这里好像也没什么好说的?硬要说些什么的话:

在第一个for循环中他能智能识别到我们想要遍历的迭代器中的对象是什么,不需要像java中的增强for循环需要我们来声明出遍历的对象是什么

Use ranges and in

/**
 * Check if a number lies within a range.
 * Check if a number is out of range.
 * Check if a collection contains an object.
 * See http://kotlinlang.org/docs/reference/ranges.html#ranges
 */

fun main(args: Array<String>) {
    val x = args[0].toInt()
    //Check if a number lies within a range:
    val y = 10
    if (x in 1..y - 1)
        println("OK")

    //Iterate over a range:
    for (a in 1..5)
        print("${a} ")

    //Check if a number is out of range:
    println()
    val array = arrayListOf<String>()
    array.add("aaa")
    array.add("bbb")
    array.add("ccc")

    if (x !in 0..array.size - 1)
        println("Out: array has only ${array.size} elements. x = ${x}")

    //Check if a collection contains an object:
    if ("aaa" in array) // collection.contains(obj) is called
        println("Yes: array contains aaa")

    if ("ddd" in array) // collection.contains(obj) is called
        println("Yes: array contains ddd")
    else
        println("No: array doesn't contains ddd")
}

这个例子中有三个小例子,先看第一个吧:

    val x = args[0].toInt()
    //Check if a number lies within a range:
    val y = 10
    if (x in 1..y - 1)
        println("OK")

    //Iterate over a range:
    for (a in 1..5)
        print("${a} ")

首先我们可以用if来判断一个参数是不是在一个范围中,太简单了没什么好讲的啊?

然后也可以在一个范围中进行迭代

再看第二个:

    //Check if a number is out of range:
    println()
    val array = arrayListOf<String>()
    array.add("aaa")
    array.add("bbb")
    array.add("ccc")

    if (x !in 0..array.size - 1)
        println("Out: array has only ${array.size} elements. x = ${x}")

其实有了第一个小例子就没必要写这个第二个了吧?不说了

看第三个:

    //Check if a collection contains an object:
    if ("aaa" in array) // collection.contains(obj) is called
        println("Yes: array contains aaa")

    if ("ddd" in array) // collection.contains(obj) is called
        println("Yes: array contains ddd")
    else
        println("No: array doesn't contains ddd")
}

这个就有意思多了,我们能通过in操作符来判断一个集合是否包含一个对象,("ddd" in array)相当于调用了array.contans("ddd"),这段代码看起来是理所当然的,但要自己写我觉得不能一下子想起来

Use when

/**
 * See http://kotlinlang.org/docs/reference/control-flow.html#when-expression
 */

fun main(args: Array<String>) {
    cases("Hello")
    cases(1)
    cases(0L)
    cases(MyClass())
    cases("hello")
}

fun cases(obj: Any) {
    when (obj) {
        1 -> println("One")
        "Hello" -> println("Greeting")
        is Long -> println("Long")
        !is String -> println("Not a string")
        else -> println("Unknown")
    }
}

class MyClass() {
}

when操作符用起来很爽,进化了的switch,能判断是否相同,能进行类型判断,还有一个else来处理别的情况,相当于default

when语句也能判断范围,例如我下面这个,但我不知道如何才能用when操作符判断其是否大于一个数字

in (10..Int.MAX_VALUE) -> println("bigger than 10 and smaller than Int.MAX_VALUE")

相关文章

  • 20170608_kotlin入门_part1

    本来嘛在IDEA的KotlinEDU已经完成一大半的入门小测试了,但换了电脑,IDEA更新成2017的后,发现Ko...

  • RXSwift学习资料

    使用自带教程入门 RxSwift 入坑手册 Part0 - 基础概念 RxSwift 入坑手册 Part1 - 示...

  • symfony4 从0开始

    part1:根据symfony4的入门过一遍+路由介绍(见@route): composer create-pro...

  • WxPyhon入门-part1

    随着近几年python的大火,越来越多的人开始使用python,大到人工智能,小到桌面小工具,python无所不能...

  • 不可思议的SmartArt

    SmartArt Part1 为什么要用SmartArt?几秒钟完成文字转换示意图 Part2快速入门 Step1...

  • awk 入门与进阶 part1—快速入门

    awk 的结构 由一个单独的模式–动作语句(pattern-action statement) 组成。 awk的运...

  • 20170625_kotlin入门_part3

    part1 part2 这是入门系列的第三部分,前两章节可以在上面进入 Callable references R...

  • 产品入门part1 - 产品视角

    01 产品人具备的三大视角 产品人需要的三大视角,用户视角+产品视角+商业视角。 案例: 用户视角=体验:最浅层的...

  • 《悄悄说玛雅历》的目录

    今天把目录整理了出来,供大家参考。 悄悄说玛雅历 目录 Part1 入门:遇见玛雅会幸福 一、13月亮28天历是什...

  • 思维导图训练营介绍

    本课程包含 2大剧情线,7个核心知识点 Part1 思维导图-入门 Day1 图导思维 我们思维困境 用思维导图,...

网友评论

      本文标题:20170608_kotlin入门_part1

      本文链接:https://www.haomeiwen.com/subject/qxpzhxtx.html