-
多平台项目
多平台项目的特性目前还处于测试阶段,这个特性方便我们进行代码复用,比如同一份业务逻辑的代码可以用来允许js项目,也可以用来运行java项目。在多平台项目中,主要存在三大模块
- 公共模块(common module)该模块的代码平台无关,或者是一些api的声明(声明的实现在platform module中)
- 平台模块(platform module)该模块的代码与平台特性相关。
- 一般模块 (regular module) ,依赖平台模块或被平台模块依赖
当我们为某一个平台编译多模块项目时,只有该平台对应的平台模块和公共模块被编译
以上仅仅是项目结构,那么如何在语言层面上进行支持呢?kotlin提供了expected和actual两个关键字。expected一般在公共模块中进行api的声明,actual关键字用来在平台模块进行具体的实现。
公共模块:
// expected platform-specific API:
expect fun hello(world: String): String
fun greet() {
// usage of the expected API:
val greeting = hello("multi-platform world")
println(greeting)
}
expect class URL(spec: String) {
open fun getHost(): String
open fun getPath(): String
}
JVM下 平台模块
actual fun hello(world: String): String =
"Hello, $world, on the JVM platform!"
// using existing platform-specific implementation:
actual typealias URL = java.net.URL
访问http://kotlinlang.org/docs/reference/multiplatform.html获取更多信息
-
其他语言特性
annotations中的参数可以使用中括号来代表数组,旧版本使用arrayOf
@CacheConfig(cacheNames = ["books", "default"])
public class BookRepositoryImpl {
// ...
}
Lateinit修饰符可以用来修饰局部变量(旧版本只能修饰全局变量)
lateinit var third: Node<Int>
val second = Node(2, next = { third })
val first = Node(1, next = { second })
third = Node(3, next = { first })
检验lateinit修饰的变量是否完成了初始化
println("isInitialized before assignment: " + this::lateinitVar.isInitialized)
lateinitVar = "value"
println("isInitialized after assignment: " + this::lateinitVar.isInitialized)
内联方法的参数如果是一个方法的话,该参数方法可以有默认实现
inline fun <E> Iterable<E>.strings(transform: (E) -> String = { it.toString() }) =
map { transform(it) }
val defaultStrings = listOf(1, 2, 3).strings()
val customStrings = listOf(1, 2, 3).strings { "($it)" }
fun main(args: Array<String>) {
println("defaultStrings = $defaultStrings")
println("customStrings = $customStrings")
}
更加机智的类型推断。firstChar变量是由变量s使用安全操作符as?转换的,并且firstChar进行了空判断,所以得出s必然为CharSequence类型。所以类型推断有两个要素:1.as?操作符转换 2.空判断
fun countFirst(s: Any): Int {
val firstChar = (s as? CharSequence)?.firstOrNull()
if (firstChar != null)
return s.count { it == firstChar } // s: Any is smart cast to CharSequence
val firstItem = (s as? Iterable<*>)?.firstOrNull()
if (firstItem != null)
return s.count { it == firstItem } // s: Any is smart cast to Iterable<*>
return -1
}
fun main(args: Array<String>) {
val string = "abacaba"
val countInString = countFirst(string)
println("called on \"$string\": $countInString")
val list = listOf(1, 2, 3, 1, 2)
val countInList = countFirst(list)
println("called on $list: $countInList")
lamble表达式内部的类型推断。必要条件:1.变量x为局部变量 2.对变量x空判断
fun main(args: Array<String>) {
val flag = args.size == 0
var x: String? = null
if (flag) x = "Yahoo!"
run {
if (x != null) {
println(x.length) // x is smart cast to String
}
}
}
未完待续。。。