跳到主要内容

创建一个 Message 实体

Sisyphus 在 Kotlin 中使用 Protobuf 提供了一套简单易用的 DSL API 来构建 Message 实体。

message EchoResponse {
string content = 1;

Severity severity = 2;
}

上面的 proto 文件定义一个名为 EchoResponse 的 Message,接下来直接使用 EchoResponse DSL 创建一个 EchoResponse 实体。

val response = EchoResponse {
this.content = input.content
this.severity = input.severity
}

只需要在 Message 类型后面使用大括号,即可构建一个 Message,在 {} 代码块中可以自由设置属性。

找不到 EchoResponse 类型?

尝试在 Gradle Task 窗口执行一下 generateProtos 生成所有的 Kotlin 代码。

消息的不可变类型与可变类型

Sisyphus 为所有消息提供了两种访问接口,例如上述例子中,Sisyphus 会为 EchoResponse 消息生成两个接口, 分别是 EchoResponseMutableEchoResponse

EchoResponse 为不可变接口,是访问 Protobuf 消息的基本入口,一般情况下我们只需要 import 此接口即可。

MutableEchoResponse 为可变接口,一般情况下会被各种消息 DSL 所隐藏,会放在特殊的 internal 包中。

EchoResponse { // this: MutableEchoResponse
this.content = input.content
this.severity = input.severity
}

例如上面的例子中,在 EchoResponse DSL 展开的代码域中,提供了 MutableEchoResponse 访问。

当消息脱离创建消息 DSL 代码域之后,就是不可变访问。关于可变与不可变访问的优点,可以参考 Kotlin 的 var 与 val 设计。

为消息重新赋值

消息创建好了之后,可以通过 invoke DSL 重新展开 MutableEchoResponse 代码域。

val response = EchoResponse {
this.content = input.content
this.severity = input.severity
}
val newResponse = response.invoke { // 也可以省略成 response {
this.content = "new content"
}
注意

但是值得注意的是,在 invoke DSL 会创建一个新的 Message 实体,而并非在原来的实体上赋值。

response !== newResponse // response 与 newResponse 并不是同一个对象