解析Kotlin-koans学习kotlin编程(二)

解析Kotlin-koans学习kotlin编程(二)_第1张图片

准备工作

Kotlin-koans是Kotlin官方推出的一个开源项目,该项目通过一系列TDD的任务来帮助你尽快上手kotlin语言。
在开始本系列之前你得先准备以下环境:

  1. jetbrains的idea
  2. gradle

task01:idea自动转换java代码为kotlin

语言和ide一家亲是有多牛,这个系列的第一个任务就迫不及待的要给大家展示。IntelliJ IDEA 或 Android Studio里,你复制一段java代码粘贴到kt文件(kotlin的代码文件后缀是kt)里时,ide会自动帮你转换为kotlin文件,而且转换的还不错。
这里我们先来看test的内容,显然是要把一个int的列表转换为字符串舒输出:

class N01JavaToKotlinConverterKtTest {
    @Test fun collection() {
        assertEquals("{1, 2, 3, 42, 555}", task1(listOf(1, 2, 3, 42, 555)))
    }
}

在task01对应的src目录里放了原有的java代码:

    public String task1(Collection collection) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            Integer element = iterator.next();
            sb.append(element);
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }

我们复制java代码粘贴到task1的kt文件里,idea会自动提示我们转换:


解析Kotlin-koans学习kotlin编程(二)_第2张图片
image.png

点击yes之后会得到转换的结果,一般情况下都不需要手工调整。用得到的结果替换原有的task1占位的函数,运行task01对应的测试即可完成task01了。

fun task1(collection: Collection): String {
    val sb = StringBuilder()
    sb.append("{")
    val iterator = collection.iterator()
    while (iterator.hasNext()) {
        val element = iterator.next()
        sb.append(element)
        if (iterator.hasNext()) {
            sb.append(", ")
        }
    }
    sb.append("}")
    return sb.toString()
}
扩展问题

这里留个坑,等遇到自动转换的问题再回过头来慢慢补上

task02:kotlin的命名参数

先看task02对应的测试代码和我们题目:

class N02NamedArgumentsKtTest {
    @org.junit.Test fun testJoinToString() {
        assertEquals("{1, 2, 3, 42, 555}", task2(listOf(1, 2, 3, 42, 555)))
    }
}
fun task2(collection: Collection): String {
    todoTask2()
    return collection.joinToString()
}

和task01的测试目标几乎一样,再看看题目,要求我们用collection对应库自带的函数joinToString来解决问题。
看一下joinToString方法的代码:

public fun  Iterable.joinToString(
separator: CharSequence = ", ", 
prefix: CharSequence = "", 
postfix: CharSequence = "", 
limit: Int = -1, 
truncated: CharSequence = "...", 
transform: ((T) -> CharSequence)? = null): String {
    return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString()
}

如果我们按照正常写法得出的答案将是这样的:

fun task2(collection: Collection): String {
//    todoTask2()
    return collection.joinToString(", ","{","}",-1,"...")
}

再看看标准答案:

fun task2(collection: Collection): String {
    return collection.joinToString(prefix = "{", postfix = "}")
}

这里直接使用了命名参数,其他几个参数采用默认值的方式。

问题解析

例如如下的函数:

fun testFun(str: String,
upFlag: Boolean = true,
leftFlag: Boolean = true,
newFlag: Boolean = false,
wordSpec: String= "kkk") {
}

其中后4个参数都给出了默认值,接下来看几个调用例子
例1 testFun("aaa")//这样是可以的
例2 testFun("aa",true)//这样是可以的相当于testFun("aa",true,true,false,"kkk")
例3 testFun("aa","aa")//错误
例1例2大大简化了我们写参数的数量,但是例3就不行,例3就相当于testFun("aa","aa",true,false,"kkk")参数2是boolean,结果我们传的是String

例3改成testFun("aa",wordSpec="aa")//这样是可以的解决了
相当于testFun("aa",true,true,false,"aa") 调用函数时仅其中某一参数不用默认值,这还是比较爽的,这些情景在写一些配置类的时候会经常遇到,简直懒癌福音。

你可能感兴趣的:(解析Kotlin-koans学习kotlin编程(二))