Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何与Kotlin的类型安全构建器一起工作?_Kotlin - Fatal编程技术网

如何与Kotlin的类型安全构建器一起工作?

如何与Kotlin的类型安全构建器一起工作?,kotlin,Kotlin,我看过很多教程,但仍然不知道它是如何工作的。我理解了它的主要思想:一个用数据保存函数的函数,但我看不出数据是如何存储的,在哪里存储的,谁调用负责存储数据的函数。其他教程似乎只显示了一段代码,对我帮助不大。你能给我一个完整简单的例子,一个普通的类,比如一个人吗?我也对一些细节感兴趣。以下是我写的: data class Person( var name: String? = null, var age: Int? = null, val childr

我看过很多教程,但仍然不知道它是如何工作的。我理解了它的主要思想:一个用数据保存函数的函数,但我看不出数据是如何存储的,在哪里存储的,谁调用负责存储数据的函数。其他教程似乎只显示了一段代码,对我帮助不大。你能给我一个完整简单的例子,一个普通的类,比如一个人吗?

我也对一些细节感兴趣。以下是我写的:

data class Person(
        var name: String? = null,
        var age: Int? = null,
        val children: MutableList<Person> = ArrayList()
) {
    fun child(init: Person.() -> Unit) = Person().also {
        it.init()
        children.add(it)
    }
}

fun person(init: Person.() -> Unit) = Person().apply { init() }

fun main(args: Array<String>) {
    val p = person {
        name = "Mommy"
        age = 33
        child {
            name = "Gugu"
            age = 2
        }
        child {
            name = "Gaga"
            age = 3
        }
    }
    println(p)
}
科特林DSLs Kotlin非常适合编写自己的领域特定语言,也称为。Anko就是使用这种DSL的例子之一。这里您需要了解的最重要的语言特性是调用,您已经使用了它:
Test.(->Unit

带接收器的函数文字-基础 Kotlin支持“具有接收者的函数文本”的概念。这使我们能够调用函数体中函数文本的接收器上的方法,而无需任何特定的限定符。这与扩展函数非常类似,在扩展函数中,还可以访问扩展内部的接收方对象的成员

一个简单的例子是
apply

public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
我们实例化一个
Bar
对象,并对其调用
apply
Bar
的实例成为“接收者”。在
{}
(lambda表达式)中作为参数传递的
,不需要使用其他限定符来访问和修改显示的可见属性
颜色
文本

DSL中带接收器的函数文本 如果您查看本文档中的示例,您会看到以下内容:

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
}
html()。在函数体中,您可以看到它是如何使用的:创建
HTML
的一个实例,并对其调用
init

利益 这种高阶函数的调用者需要一个带有receiver的函数文本(如
html()
),您可以使用任何可见的
html
函数和属性,而无需附加限定符(如
this
),正如您在调用中看到的:

html {       // lambda with receiver begins here
    body()   // calling a method on the receiver object
}
例子
我已经编写了一个DSL示例,并在一个示例中非常详细地描述了它。也许这也有帮助。

所以,在fun child内部,当您调用child.init(),name=“Gugu”和age=2(用main编写)时,与在fun child中编写child.name=“Gugu”和child.age=2是一样的,对吗?是的,因为在
init
块中,
被分配给
实例。那么功能人员仅用于构建目的?如果想要在构建之后获得一些值,我必须调用Person类,对吗?是的,您可以从中获得一个常规数据类。但是在以后的任何时候,你都可以再次调用
p.child{…}
Awesome!谢谢
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
}
html {       // lambda with receiver begins here
    body()   // calling a method on the receiver object
}