Kotlin基本语法

Kotlin包名,函数


主要参考:https://www.gitbook.com/book/huanglizhuo/kotlin-in-chinese/details 这本书,大神们也可也自行前往阅读,这篇文章主要是对一些不起眼的知识点进行了梳理和总结,让大家对kotlin的了解更进一步。有很多人说资料太少了,这里我拿了鸿洋大神整理出来的一些别人分享的东西,地址连接http://blog.csdn.net/sinat_36668731/article/details/72529986,在文章的下面干货集锦。

1.定义包名
在源文件的开头定义包名:

package foo.bar
import java.util.*

fun bza() {}

class Goo {}
//...

kotlin源文件不需要和文件夹路径一致:源文件可以放在任何文件目录
源文件的所有内容(比如类和函数)都被包声明包括。因此在上面的例子中, bza() 的全名应该是 foo.bar.bza ,Goo 的全名是 foo.bar.Goo。
如果没有指定包名,那这个文件的内容就从属于默认 “default” 包。

默认导入的包名:

  • kotlin.
  • kotlin.annotation.
  • kotlin.collections.
  • kotlin.comparisons. (since 1.1)
  • kotlin.io.
  • kotlin.ranges.
  • kotlin.sequences.
  • kotlin.text.

一些增强包会根据平台来决定是否默认导入:

  • JVM
  • java.lang.
  • kotlin.jvm.
  • JS:
  • kotlin.js.*

Imports

除了模块中默认导入的包,每个文件都可以有它自己的导入指令。导入语法的声明在grammar中描述。
我们可以导入一个单独的名字,比如下面这样:

import foo.Bar // Bar 现在可以不用条件就可以使用

或者范围内的所有可用的内容 (包,类,对象,等等):

import foo.*/ /foo 中的所有都可以使用

如果命名有冲突,我们可以使用 as 关键字局部重命名解决冲突

import foo.Bar // Bar 可以使用
import bar.Bar as bBar // bBar 代表 'bar.Bar'

import关键字不局限于导入类;您也可以使用它来导入其他声明:

  • 顶级函数与属性
  • 在对象声明中声明的函数和属性
  • 枚举常量

可见性和包嵌套

如果最顶的声明标注为 private , 那么它是自己对应包私有 。如果包内有私有的属性或方法,那它对所有的子包是可见的。

注意包外的的成员是默认不导入的,比如在导入 foo.bar 后我们不能获得 foo 的成员,这个和java都是一样的

函数定义

//Int 为参数,返回值也是Int类型,和swift一样
fun sum(a: Int , b: Int) : Int{
    return a + b
}

fun main(args: Array<String>) {
  print("sum of 3 and 5 is ")
  println(sum(3, 5))
}

该函数只有一个表达式函数体以及一个自推导型的返回值:

fun sum(a: Int, b: Int) = a + b //kotlin方法会根据表达式自动识别出返回值类型

fun main(args: Array<String>) {
  println("sum of 19 and 23 is ${sum(19, 23)}")
}

返回一个没有意义的值(类似于java中的void ):

fun printSum(a: Int, b: Int): Unit {
  println("sum of $a and $b is ${a + b}")
}

fun main(args: Array<String>) {
  printSum(-1, 8)
}

Unit 的返回类型可以省略:

fun printSum(a: Int, b: Int) {
  println("sum of $a and $b is ${a + b}")
}

fun main(args: Array<String>) {
  printSum(-1, 8)
}

函数参数可以设置默认值,当参数被忽略时会使用默认值。这样相比其他语言可以减少重载, 默认值可以通过在type类型后使用=号进行赋值

// 这里off、len都使用了默认值,
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size() ) {
...
}

命名参数
在调用函数时可以参数命名。这对于那种有大量参数的函数是很方便的.

fun reformat(str: String, normalizeCase: Boolean = true,upperCaseFirstLetter: Boolean = true,
             divideByCamelHumps: Boolean = false,
             wordSeparator: Char = ' ') {
...
}

我们可以使用默认参数

reformat(str)

然而当调用非默认参数是就需要像下面这样:

reformat(str, true, true, false, ' ')

使用命名参数我们可以让代码可读性更强:(其实是把默认参数类型给省去了)

reformat(str,
    normalizeCase = true,
    uppercaseFirstLetter = true,
    divideByCamelHumps = false,
    wordSeparator = ' '
  )

如果不需要全部参数的话可以这样:

reformat(str, wordSeparator = ' ')

注意:命名参数语法不能够被用于调用Java函数中,因为Java的字节码不能确保方法参数命名的不变性

单表达式函数
当函数只返回单个表达式时,大括号可以省略并在 = 后面定义函数体

fun double(x: Int): Int = x*2

在编译器可以推断出返回值类型的时候,返回值的类型可以省略:

fun double(x: Int) = x * 2

变长参数
函数的参数(通常是最后一个参数)可以用 vararg 修饰符进行标记:

fun asList<T>(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts)
        result.add(t)
    return result
}

标记后,允许给函数传递可变长度的参数:

val list = asList(1, 2, 3)

lambda(匿名函数)

// 测试
fun main(args: Array<String>) {
    val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
    println(sumLambda(1,2))  // 输出 3
}

函数范围

每个函数都有自己的作用域,也就是所谓的函数范围。Kotlin 中可以在文件顶级声明函数,这就意味者你不用像在Java,C#或是Scala一样创建一个类来持有函数。除了顶级函数,Kotlin 函数可以声明为局部的,作为成员函数或扩展函数。

局部函数
Kotlin 支持局部函数,比如在一个函数包含另一函数。

fun dfs(graph: Graph) {
  fun dfs(current: Vertex, visited: Set<Vertex>) {
    if (!visited.add(current)) return
    for (v in current.neighbors)
      dfs(v, visited)
  }

  dfs(graph.vertices[0], HashSet())
}

局部函数可以访问外部函数的局部变量(比如闭包)

fun dfs(graph: Graph) {
    val visited = HashSet<Vertex>()
    fun dfs(current: Vertex) {
        if (!visited.add(current)) return 
        for (v in current.neighbors)
            dfs(v)
    }
    dfs(graph.vertices[0])
}

局部函数甚至可以返回到外部函数

fun reachable(from: Vertex, to: Vertex): Boolean {
    val visited = HashSet<Vertex>()
    fun dfs(current: Vertex) {
        if (current == to) return@reachable true
        if (!visited.add(current)) return
        for (v  in current.neighbors)
            dfs(v)
    }
    dfs(from)
    return false
}

局部函数和java思路是一样,都是局部函数可以持外部函数的引用。

成员函数
成员函数是定义在一个类或对象里边的

class Sample() {
    fun foo() { print("Foo") }
}

成员函数可以用 . 的方式调用

Sample.foo()

这个的使用方法也和java一样,只不过对象不是new出来的而已,具体的后面再讲
泛型函数
函数可以有泛型参数,样式是在函数后跟上尖括号。

fun sigletonArray<T>(item: T): Array<T> {
    return Array<T>(1, {item})
}

这个思路也是和android一直的

尾递归函数
Kotlin 支持函数式编程的尾递归。这个允许一些算法可以通过循环而不是递归解决问题,从而避免了栈溢出。当函数被标记为 tailrec 时,编译器会优化递归,并用高效迅速的循环代替它。

tailrec fun findFixPoint(x: Double = 1.0): Double 
    = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))

这段代码计算的是数学上的余弦不动点。Math.cos 从 1.0 开始不断重复,直到值不变为止,结果是 0.7390851332151607 这段代码和下面的是等效的:

private fun findFixPoint(): Double {
    var x = 1.0
    while (true) {
        val y = Math.cos(x)
        if ( x == y ) return y
        x = y
    }
}

使用 tailrec 修饰符必须在最后一个操作中调用自己。在递归调用代码后面是不允许有其它代码的,并且也不可以在 try/catch/finall 块中进行使用。当前的尾递归只在 JVM 的后端中可以用。

在学习Kotlin中难免会遇到一些不懂的和一些坑,这时候就需要大家相互分享和提点,这里推荐一下Kotlin社区,欢迎大家来交流。
下面附上qq群:302755325
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值