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
Oop 将API响应转换为可为空的字符串_Oop_Kotlin_Design Patterns_Software Design - Fatal编程技术网

Oop 将API响应转换为可为空的字符串

Oop 将API响应转换为可为空的字符串,oop,kotlin,design-patterns,software-design,Oop,Kotlin,Design Patterns,Software Design,我使用的API返回(除其他字段外)一个必需的telephone1和一个可选的telephone2。但是,我获取的JSON始终包含这两个字段,缺少的条目显示为空字符串 { "telephone1": "+1 555 1234", "telephone2": "" } 当响应映射到pojo时,是否最好将空字符串转换为null?以便: data class( val telephone1: String

我使用的API返回(除其他字段外)一个必需的
telephone1
和一个可选的
telephone2
。但是,我获取的JSON始终包含这两个字段,缺少的条目显示为空字符串

{
   "telephone1": "+1 555 1234",
   "telephone2": ""
}
当响应映射到pojo时,是否最好将空字符串转换为null?以便:

data class(
   val telephone1: String,
   val telephone2: String?
}

对我来说,这更好地传达了可能的状态。我应该吗?有缺点吗?

乍一看,问题归结为进一步数据处理之前的不同检查:
x==null
x.isEmpty()
。但是,尽管空性检查通常由kotlin编译器强制执行(与非空性不同),但它似乎是一个更好的选择

但仍有一些情况下使用
null
(无任何编译器错误)可能会导致运行时出现问题(主要与不强制为null的语言的互操作有关):例如
null
到文本字符串
“null”
(与另一个字符串连接时)的隐式转换,甚至在传递给接受
String的方法时使用NPE(),未正确注释

遵循DDD原则,更好的选择是声明单独的数据类型:

密封类可选电话号码
数据类PhoneNumber(val-value:String):OptionalPhoneNumber()//您还可以在init块中添加一些检查,确保'value'实际上是一个电话号码,而不仅仅是一组随机字符
对象EmptyPhoneNumber:OptionalPhoneNumber()
并将数据类定义为:

数据类数据(
val电话1:电话号码,
val电话2:可选电话号码
)
类型系统将强制您执行
x is PhoneNumber
检查,并且由于智能强制转换,它的进一步使用将是类型安全的:

if(电话2是电话号码){
println(电话2.值)
}

您实际使用哪种API?我工作的一家大公司的内部API。这意味着它不是公共的,但我对它也没有影响。你在问“如何实现此(反)序列化?”或“强调缺少字符串值-null或空字符串更好吗?”强调缺少字符串值-null或空字符串更好吗。如果后端开发人员的选择——他选择了一个空字符串——应该对我的选择有任何影响。你说“主要与没有强制可空性的语言的互操作有关”,如果互操作不存在呢?它是Java和Kotlin的混合体;新代码是用Kotlin编写的,此pojo将仅在新特性中使用。可能存在哪些非互操作问题?而且,这不是重新创建null的示例吗?>这不是重新创造空的例子吗?不,不是
EmptyPhoneNumber
表示缺少
OptionalPhoneNumber
,而不是一般缺少某些类型的数据(如
可选
中的
null
None
)。例如,如果您以相同的样式定义
OptionalAddress
,则会有
EmptyAddress
,区别于
EmptyPhoneNumber
,除了提到的隐式转换为“null”字符串之外,还会有哪些非互操作问题,使用
null
会稍微放松类型系统。这将在没有警告的情况下编译并在运行时工作:
val a:PhoneNumber?=无效的val b:地址?=a作为地址?
。这将发出编译器警告(
此强制转换永远不会成功
)和运行时异常:
val a=EmptyPhoneNumber;val b:OptionalAddress=(a作为OptionalAddress)
这可能不是一个实际问题,只是拒绝了一些额外的保护。