函数

// 函数定义及调用
fun double(x: Int): Int {
return 2*x
}
val result = double(2)
// 调用方法
Sample().foo() // create instance of class Sample and call foo
// 参数语法
fun powerOf(number: Int, exponent: Int) {
...
}
// 缺省参数
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size()) {
...
}
// 带缺省参数的方法被覆盖时不能带缺省参数
open class A {
open fun foo(i: Int = 10) { ... }
}
class B : A() {
override fun foo(i: Int) { ... } // no default value allowed
}
// 缺省参数之后还可以有不带缺省值的参数
fun foo(bar: Int = 0, baz: Int) { /* ... */ }
foo(baz = 1) // The default value bar = 0 is used
// 缺省参数之后还可以有 lambda 参数
fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { /* ... */ }
foo(1) { println("hello") } // Uses the default value baz = 1
foo { println("hello") } // Uses both default values bar = 0 and baz = 1
// 具名参数
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 = '_')
// 展开(spread)运算符
fun foo(vararg strings: String) { /* ... */ }
foo(strings = *arrayOf("a", "b", "c"))
// 返回类型为Unit的函数
fun printHello(name: String?): Unit {
if (name != null)
println("Hello ${name}")
else
println("Hi there!")
// `return Unit` or `return` is optional
}
fun printHello(name: String?) {
...
}
// 表达式函数
fun double(x: Int): Int = x * 2
fun double(x: Int) = x * 2
// varargs
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) // ts is an Array
result.add(t)
return result
}
val list = asList(1, 2, 3)
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
// 扩展函数的中缀表示法
infix fun Int.shl(x: Int): Int {
// ...
}
// calling the function using the infix notation
1 shl 2
// is the same as
1.shl(2)
// 成员函数的中缀表示法
class MyStringCollection {
infix fun add(s: String) { /* ... */ } fun build() {
this add "abc" // Correct
add("abc") // Correct
add "abc" // Incorrect: the receiver must be specified
}
}
// 局部函数
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])
}
// 成员函数
class Sample() {
fun foo() { print("Foo") }
}
Sample().foo() // creates instance of class Sample and calls foo
// 泛型函数
fun <T> singletonList(item: T): List<T> {
// ...
}

高阶函数和lambda表达式(Higher-Order Functions and Lambdas)

高阶函数:将函数作为参数或返回值的函数。

lambda表达式的特点

  • lambda表达式使用尖括号
  • 参数(类型可省略)位于->符号之前
  • 函数体位于->符号之后
  • 不能指定返回类型
  • lambda表达式参数位于最后时可以脱离小括号
  • return语句将跳出包含lambda表达式的外围函数

    匿名函数(Anonymous Functions)
  • 没有函数名的函数
  • 可以指定返回类型
  • 必须包含在小括号中
  • return语句跳出匿名函数自身

    高阶函数和匿名函数统称函数字面量(function literal)。
// 高阶函数
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
// 使用函数引用(function references)将函数作为参数传给函数
fun toBeSynchronized() = sharedResource.operation()
val result = lock(lock, ::toBeSynchronized)
// 使用lambda表达式
val result = lock(lock, { sharedResource.operation() })
// lambda表达式是最后一个参数时,括弧可以省略
lock (lock) {
sharedResource.operation()
}
// 高阶函数map
fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
val result = arrayListOf<R>()
for (item in this)
result.add(transform(item))
return result
}
val doubled = ints.map { value -> value * 2 }
// 只有一个参数时可以使用隐式参数it
ints.map { it * 2 }
// LINQ风格的代码
strings.filter { it.length == 5 }.sortBy { it }.map { it.toUpperCase() }
// 不需要使用的参数可以用下划线表示
map.forEach { _, value -> println("$value!") }
// lambda表达式语法
val sum = { x: Int, y: Int -> x + y }
val sum: (Int, Int) -> Int = { x, y -> x + y }
ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'
// lambda表达式隐式返回最后一个表达式的值
// 两段代码效果相同
ints.filter {
val shouldFilter = it > 0
shouldFilter
}
ints.filter {
val shouldFilter = it > 0
return@filter shouldFilter
}
// 匿名函数
fun(x: Int, y: Int): Int = x + y
fun(x: Int, y: Int): Int {
return x + y
}
// 使用匿名函数
// 参数类型可省略
ints.filter(fun(item) = item > 0)
// 闭包(Closures)
var sum = 0
ints.filter { it > 0 }.forEach {
sum += it
}
print(sum)
// 带 receiver(隐含调用方)的函数字面量
sum : Int.(other: Int) -> Int
1.sum(2)
val sum = fun Int.(other: Int): Int = this + other
// String.(Int) -> Boolean 与 (String, Int) -> Boolean 相互兼容
val represents: String.(Int) -> Boolean = { other -> toIntOrNull() == other }
println("123".represents(123)) // true
fun testOperation(op: (String, Int) -> Boolean, a: String, b: Int, c: Boolean) =
assert(op(a, b) == c)
testOperation(represents, "100", 100, true) // OK
// 通过上下文推导 receiver
class HTML {
fun body() { ... }
}
fun html(init: HTML.() -> Unit): HTML {
val html = HTML() // create the receiver object
html.init() // pass the receiver object to the lambda
return html
}
html { // lambda with receiver begins here
body() // calling a method on the receiver object
}

Kotlin语言学习笔记(4)的更多相关文章

  1. Kotlin语言学习笔记(2)

    类(classes) // 类声明 class Invoice { } // 空的类 class Empty // 主体构造器(primary constructor) class Person co ...

  2. Kotlin语言学习笔记(1)

    fun main(args: Array<String>) { println("Hello, World!") } 基本语法 声明常量用val,声明变量用var,声明 ...

  3. Kotlin语言学习笔记(6)

    运算符重载(Operator overloading) 一元运算符 Expression Translated to +a a.unaryPlus() -a a.unaryMinus() !a a.n ...

  4. Kotlin语言学习笔记(5)

    委托模式(Delegation) 类的委托 interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fu ...

  5. Kotlin语言学习笔记(3)

    数据类(Data Classes) data class User(val name: String, val age: Int) 编译器自动生成的有: equals()/hashCode() toS ...

  6. Kotlin语言学习笔记(7)

    反射 // 反射 val c = MyClass::class val c2 = MyClass::class.java // 获取KClass的引用 val widget: Widget = ... ...

  7. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  8. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  9. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

随机推荐

  1. js一种继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。

    js一种继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法. function ClassA(sColor) { this.color = sColor; } ClassA ...

  2. 监督学习(Supervised learning)

    定义符号 m:训练样本的数目 n:特征的数量 x‘s:输入变/特征值 y‘s:输出变量/目标变量 (x,y):训练样本 ->(x(i),y(i)):训练集,第i个训练样本,i=1,2..,m 监 ...

  3. [C++ Primer] : 第14章: 重载运算符与类型转换

    基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...

  4. Sublime Text 3 最新可用注册码(免破解)

    12年的时候分享过Sublime Text 2的注册码和破解方法.4年后容我更新一下Sublime Text 3的注册码.. 最好还是购买正版主持版权.:D. 以下两枚注册码用最新的Sublime T ...

  5. DHTMLX学习总结

    1.布局 Lyout = new dhtmlXLayoutObject(document.body, "2U"); 2.Grid grid.setHeader("#mas ...

  6. Appscan安装问题记录 + 最后问题解决的方法 和安装步骤

    最后环节有问题,无法创建常规任务,腰折, 估计是在安装环节不可以忽略下面的报错,有空解决一下这个问题 解决: 安装了一个虚拟机W7系统 可以安装成功 appscan9.0.3要W8的系统 最后装了ap ...

  7. 2018-2019 Exp3 免杀原理与实践

    2018-2019 Exp3 免杀原理与实践 目录 一.实验内容说明及基础问题回答 二.实验过程 Task1 1.使用msf编码器生成后门程序及检测 Task1 2.msfvenom生成jar等文件 ...

  8. 【Ethereum】以太坊ERC20 Token标准完整说明

    什么是ERC20 token 市面上出现了大量的用ETH做的代币,他们都遵守REC20协议,那么我们需要知道什么是REC20协议. 概述 token代表数字资产,具有价值,但是并不是都符合特定的规范. ...

  9. sublime text 3 3143

    下载链接:https://download.sublimetext.com/Sublime%20Text%20Build%203143%20x64%20Setup.exe 注册信息:sublime t ...

  10. vmware 共享文件夹(win10下的vmware安装了centos7)

    最近研究下了docker.我的笔记本是win10系统,就尝试使用了 win10的hyper-v虚拟化技术,总是感觉占用系统较多,于是换成了vmware,在虚拟机中安装 docker容器服务. 考虑到开 ...