准备工作
Kotlin-koans是Kotlin官方推出的一个开源项目,该项目通过一系列TDD的任务来帮助你尽快上手kotlin语言。
在开始本系列之前你得先准备以下环境:
- jetbrains的idea
- 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<Integer> collection) {
StringBuilder sb = new StringBuilder();
sb.append("{");
Iterator<Integer> 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会自动提示我们转换:
点击yes之后会得到转换的结果,一般情况下都不需要手工调整。用得到的结果替换原有的task1占位的函数,运行task01对应的测试即可完成task01了。
fun task1(collection: Collection<Int>): 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<Int>): String {
todoTask2()
return collection.joinToString()
}
和task01的测试目标几乎一样,再看看题目,要求我们用collection
对应库自带的函数joinToString
来解决问题。
看一下joinToString方法的代码:
public fun <T> Iterable<T>.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<Int>): String {
// todoTask2()
return collection.joinToString(", ","{","}",-1,"...")
}
再看看标准答案:
fun task2(collection: Collection<Int>): 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")
调用函数时仅其中某一参数不用默认值,这还是比较爽的,这些情景在写一些配置类的时候会经常遇到,简直懒癌福音。