title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url | translator | translator_url |
---|---|---|---|---|---|---|---|---|---|---|---|---|
[译]The Dot Operator |
2013-04-01 03:00:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
警告:这是愚人节的帖子 无点 风格是现代功能编程中的一个大趋势:它允许操纵函数,而不用提及它们的参数,这使得代码简洁和组合。以下是维基百科的例子:
{% raw %}
{% endraw %}mf = (. map) . (.) . filter
{% raw %}
{% endraw %}这个函数用 Haskell 编写,它构成了一个带有 filter()函数的 map()函数。如您所见,无点式的风格主要依靠点。 Kotlin 本身不是功能性语言,但我们很乐意借用其他语言的实用功能。所以,今天我会写点点。
我们在 Kotlin 中介绍点运算符。像往常一样,它按照惯例工作。如果有这样的功能
{% raw %}
{% endraw %}fun Foo.dot() {
println("a dot!")
}
{% raw %}
{% endraw %}在 Foo 类型的表达式后面会有一个点(“。”)被调用:
{% raw %}
{% endraw %}fun test(f: Foo) {
f.foo()
Foo().bar().baz()
}
{% raw %}
{% endraw %}此功能打印“一个点!”两次:一个 Foo 后每个点一次。 bar()函数不返回 Foo,所以后面的点不算。
如果我的 dot()函数返回某些东西,例如另一个 Foo,该怎么办?
{% raw %}
{% endraw %}class Foo(val count: Int)
fun Foo.dot(): Foo {
return Foo(count + 1)
}
{% raw %}
{% endraw %}那么当然,它的结果是用来调用点后的任何东西:
{% raw %}
{% endraw %}println(Foo(1).count)
{% raw %}
{% endraw %}这打印 2,因为 dot()函数返回一个新的 Foo 增加计数器。 你可以看到,点运算符给了我们很多的权力,解决了以前解决的大多数问题 面向方面的编程 。
当您使用参数声明时,点操作符的真实力量来自:
{% raw %}
{% endraw %}fun Any.dot(p: Dot) {
...
}
{% raw %}
{% endraw %}该参数必须是 Dot 类型,其中有一些有趣的预定义值:
{% raw %}
{% endraw %}LEFT
RIGHT
TOP
BOTTOM
{% raw %}
{% endraw %}这些值显然对应于点的位置:
{% raw %}
{% endraw %}fun test() {
println(a.b[1..2])
}
{% raw %}
{% endraw %}有人可能认为在这个例子中,dot()被调用三次:一个用于“ab”,参数 BOTTOM,然后是“1..2”两次:首先用 LEFT,然后用 RIGHT(这些不是两个 BOTTOM ,因为“..”是一个单一的 令牌 在 Kotlin),但事实上它被称为四次,第四次(实际上是第一次)与 TOP 作为参数。 我相信你已经明白了为什么:在 Kotlin,我们永远不会忘记点点我的,这个点也是如此;其立场显然是 TOP(我们可以单独介绍) 滴滴 ()函数,但是我们发现它太不方便了)。在 j 的计数以上也是一样,点数也相同! ?等等
你可能会想知道如果定义了这样的点(),会发生什么:
{% raw %}
{% endraw %}fun Foo.dot() {
println(this.count)
}
{% raw %}
{% endraw %}在这个之间有一个点,它在 Foo.dot()函数本身中具有 Foo 类型,所以在这一点上应该递归调用 dot(),并且似乎从不终止。这被称为高阶点*,只有在 Foo 上定义了一个函数 dot1()时才执行。如果 dot1()又包含高阶点,则调用 dot2()等等:
{% raw %}
{% endraw %}fun Foo.dot1() {
println(this.count) // a call to dot2() if that is defined
}
{% raw %}
{% endraw %}这对应于罗素的设定理论的方法 类型理论 (与它的概念 类 ),这是静态类型的面向对象编程的坚实基础。
我们计划很快支持点运营商。第一个版本将被限制为基本的 ASCII 字符,如。 :; ! ?当然,我,但在将来我们计划将其扩展到其他角色,如ё。 有一个不错的点!