专栏首页一个会写诗的程序员的博客Kotlin 's Function 《Kotlin极简教程》正式上架:

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 条评论
登录 后参与评论

相关文章

  • mysql 多表关联查询 实现 全文匹配的 模糊搜索接口 SQLmysql 多表关联查询 实现 全文匹配的 模糊搜索接口 SQL

    在mysql中,有时我们在做数据库查询时,需要得到某字段中包含某个值的记录,但是它也不是用like能解决的,使用like可能查到我们不想要的记录,它比like更...

    一个会写诗的程序员
  • Kotlin 函数式编程 + 递归 : 构建 "树" 数据结构通用模型

    注意到这里的@Id 生成策略是我们自定义的: com.ak47.cms.cms.tree.CustomUUIDGenerator

    一个会写诗的程序员
  • 2. 深入理解 Cookie 与 Session ,Facade 设计模式, 分布式 Session

    "BAIDUID=40E9A74CB78CA05206FD128BEB27E014:FG=1; PSTM=1568883435; BIDUPSID=4927A1...

    一个会写诗的程序员
  • python变量的定义

            python中字符带单引号或者双引号,python都认为是字符串。

    py3study
  • Scala语言基础之结合demo和spark讲实现链式计算

    一,什么是链式计算 1,一般开发习惯把事情封装到一个方法中;链式编程思想是把要做的事情封装到block中,给外部提供一个返回这个block的方法 2,链式编程思...

    Spark学习技巧
  • 自动段指导任务(Automatic Segment Advisor)

    本文主要介绍自动段指导(Automatic Segment Advisor)任务的内容进行详细介绍。

    TeacherWhat
  • python Class:获取对象类型

    #!/usr/bin/env python3 # -*- coding: utf-8 -*-

    py3study
  • Neo4j-1.5 WHERE子句

    悠扬前奏
  • Sentence-BERT详解

    BERT和RoBERTa在文本语义相似度(Semantic Textual Similarity)等句子对的回归任务上,已经达到了SOTA的结果。但是,它们都需...

    mathor
  • 云办公的技术设备要求

    2020 年的工作正式开启,大多数开发者的开工方式是云办公。对开发者来说,云办公意味着什么?如何开始云办公?云办公的发展趋势会怎样?基于此,云加社区联手知乎科技...

    云加社区

扫码关注云+社区

领取腾讯云代金券