Kotlin 's Function 《Kotlin极简教程》正式上架:

Kotlin 's Function

1.Basic Functions

Functions are declared using the fun keyword, followed by a function name and any parameters. You can also specify the return type of a function, which defaults to Unit. The body of the function is enclosed in braces {}. If the return type is other than Unit, the body must issue a return statement for every terminating branch within the body.

fun sayMyName(name: String): String {
    return "Your name is $name" 
} 

A shorthand version of the same:

fun sayMyName(name: String): String = "Your name is $name" 

And the type can be omitted since it can be inferred:

fun sayMyName(name: String) = "Your name is $name" 

2.Function References

We can reference a function without actually calling it by prefixing the function's name with ::. This can then be passed to a function which accepts some other function as a parameter.

fun addTwo(x: Int) = x + 2
listOf(1, 2, 3, 4).map(::addTwo) 
# => [3, 4, 5, 6]

Functions without a receiver will be converted to (ParamTypeA, ParamTypeB, ...) -> ReturnType where ParamTypeA, ParamTypeB ... are the type of the function parameters and `ReturnType1 is the type of function return value.

fun foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
println(::foo::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar

3. Functions with a receiver

(be it an extension function or a member function) has a different syntax. You have to add the type name of the receiver before the double colon:

class Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function4<Foo, Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo, Foo0, Foo1, Foo2) -> Bar
// takes 4 parameters, with receiver as first and actual parameters following, in their order

// this function can't be called like an extension function, though
val ref = Foo::foo
Foo().ref(Foo0(), Foo1(), Foo2()) // compile error

class Bar {
    fun bar()
}
print(Bar::bar) // works on member functions, too.

However, when a function's receiver is an object, the receiver is omitted from parameter list, because these is and only is one instance of such type.

object Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
// takes 3 parameters, receiver not needed

object Bar {
    fun bar()
}
print(Bar::bar) // works on member functions, too.

Since kotlin 1.1, function reference can also be bounded to a variable, which is then called a bounded function reference.

fun makeList(last: String?): List<String> {
    val list = mutableListOf("a", "b", "c")
    last?.let(list::add)
    return list
}

Note: this example is given only to show how bounded function reference works. It's bad practice in all other senses.

There is a special case, though. An extension function declared as a member can't be referenced.

class Foo
class Bar {
    fun Foo.foo() {}
    val ref = Foo::foo // compile error
}

4.Inline Functions

Functions can be declared inline using the inline prefix, and in this case they act like macros in C - rather than being called, they are replaced by the function's body code at compile time. This can lead to performance benefits in some circumstances, mainly where lambdas are used as function parameters.

inline fun sayMyName(name: String) = "Your name is $name" One difference from C macros is that inline functions can't access the scope from which they're called:

inline fun sayMyName() = "Your name is $name"

fun main() {
    val name = "Foo"
    sayMyName() # => Unresolved reference: name
}

5.Lambda Functions

Lambda functions are anonymous functions which are usually created during a function call to act as a function parameter. They are declared by surrounding expressions with {braces} - if arguments are needed, these are put before an arrow ->.

{ name: String ->
    "Your name is $name" //This is returned
}

The last statement inside a lambda function is automatically the return value.

The type's are optional, if you put the lambda on a place where the compiler can infer the types.

Multiple arguments:

{ argumentOne:String, argumentTwo:String ->
    "$argumentOne - $argumentTwo"
}

If the lambda function only needs one argument, then the argument list can be omitted and the single argument be referred to using it instead.

{ "Your name is $it" }

If the only argument to a function is a lambda function, then parentheses can be completely omitted from the function call.

# These are identical
listOf(1, 2, 3, 4).map { it + 2 }
listOf(1, 2, 3, 4).map({ it + 2 })

6.Functions Taking Other Functions

As seen in "Lambda Functions", functions can take other functions as a parameter. The "function type" which you'll need to declare functions which take other functions is as follows:

Takes no parameters and returns anything

() -> Any?

Takes a string and an integer and returns ReturnType

(arg1: String, arg2: Int) -> ReturnType

For example, you could use the vaguest type, () -> Any?, to declare a function which executes a lambda function twice:

fun twice(x: () -> Any?) {
    x(); x();
}

fun main() {
    twice {
        println("Foo")
    } # => Foo
      # => Foo
}

7.Operator functions

Kotlin allows us to provide implementations for a predefined set of operators with fixed symbolic representation (like + or *) and fixed precedence. To implement an operator, we provide a member function or an extension function with a fixed name, for the corresponding type. Functions that overload operators need to be marked with the operator modifier:

data class IntListWrapper (val wrapped: List<Int>) {
    operator fun get(position: Int): Int = wrapped[position]
}

val a = IntListWrapper(listOf(1, 2, 3))
a[1] // == 2

More operator functions can be found in here

8.Shorthand Functions

If a function contains just one expression, we can omit the brace brackets and use an equals instead, like a variable assignment. The result of the expression is returned automatically.

fun sayMyName(name: String): String = "Your name is $name"

KotlinChina编程社区 微博

非常感谢您亲爱的读者,大家请多支持!!!有任何问题,欢迎随时与我交流~


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小樱的经验随笔

【Java学习笔记之八】JavaBean中布尔类型使用注意事项

JavaBean是一个标准,遵循标准的Bean是一个带有属性和getters/setters方法的Java类。 JavaBean的定义很简单,但是还有有一些地方...

3088
来自专栏函数式编程语言及工具

泛函编程(29)-泛函实用结构:Trampoline-不再怕StackOverflow

   泛函编程方式其中一个特点就是普遍地使用递归算法,而且有些地方还无法避免使用递归算法。比如说flatMap就是一种推进式的递归算法,没了它就无法使用for-...

2589
来自专栏向治洪

Ecmascript语法之Symbol

Symbol 概述 作为属性名的Symbol 实例:消除魔术字符串 属性名的遍历 Symbol.for(),Symbol.keyFor() 实例:模块的 Sin...

2159
来自专栏一个会写诗的程序员的博客

Kotlin 函数编程详解函数Kotlin 开发者社区

Functions in Kotlin are declared using the fun keyword:

863
来自专栏函数式编程语言及工具

泛函编程(10)-异常处理-Either

     上节我们介绍了新的数据类型Option:一个专门对付异常情况出现时可以有一致反应所使用的数据类型。Option可以使编程人员不必理会出现异常后应该如何...

2035
来自专栏函数式编程语言及工具

Scalaz(35)- Free :运算-Trampoline,say NO to StackOverflowError

   在前面几次讨论中我们介绍了Free是个产生Monad的最基本结构。它的原理是把一段程序(AST)一连串的运算指令(ADT)转化成数据结构存放在内存里,这个...

2108
来自专栏Ryan Miao

jackson简单使用,对象转json,json转对象,json转list

添加jackson依赖: // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/ja...

42911
来自专栏柠檬先生

es6 Symbol

1.Symbol 值通过Symbol 函数生成,凡是属性名属于Symbol 类型,就是   独一无二的,可以保证不会与其他属性名冲突。       // 没有参...

2197
来自专栏DHUtoBUAA

赋值运算符函数__from <剑指Offer>

        前段时间忙于项目,难得偷得几日闲,为即将到来的就业季做准备。在面试时,应聘者要注意多和考官交流,只有具备良好的沟通能力,才能充分了解面试官的需求...

2765
来自专栏猿人谷

编程小技巧

1.判断一个自然数是否是某个数的平方?(其实就是判断这个数一定是奇数相加的) 由于 (n+1)^2 =n^2 + 2n + 1, = ... = 1 +...

21610

扫码关注云+社区

领取腾讯云代金券