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_Kotlin Null Safety - Fatal编程技术网

在Kotlin中进行空检的最佳方法?

在Kotlin中进行空检的最佳方法?,kotlin,kotlin-null-safety,Kotlin,Kotlin Null Safety,我应该使用双=还是三= if(a === null) { //do something } 或 类似地,对于“不等于”: if(a !== null) { //do something } 或 这两种方法都生成相同的字节码,因此您可以选择自己喜欢的任何方法 A结构等式A==b被转换为 a?.equals(b) ?: (b === null) 因此,当与null进行比较时,结构等式a==null被转换为引用等式a==null 根据,优化代码没有意义,因此可以使用a==null和a!=空

我应该使用双
=
还是三
=

if(a === null)  {
//do something
}

类似地,对于“不等于”:

if(a !== null)  {
//do something
}


这两种方法都生成相同的字节码,因此您可以选择自己喜欢的任何方法

A结构等式
A==b
被转换为

a?.equals(b) ?: (b === null)
因此,当与
null
进行比较时,结构等式
a==null
被转换为引用等式
a==null

根据,优化代码没有意义,因此可以使用
a==null
a!=空



注意如果变量是可变属性,则无法在
if
语句中将其智能强制转换为不可为null的类型(因为该值可能已被另一个线程修改),而必须使用带有
let
的安全调用运算符

安全呼叫接线员
?。

a?.let {
   // not null do something
   println(it)
   println("not null")
}

您可以将其与Elvis运算符结合使用

猫王接线员
?:
(我猜是因为问号看起来像猫王的头发)

如果你想运行一段代码

a ?: run {
    println("null")
    println("The King has left the building")
}
将两者结合起来

a?.let {
   println("not null")
   println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
    println("null")
    println("When things go null, don't go with them")
}

查看有用的方法,它可能很有用:

/**
 * Performs [R] when [T] is not null. Block [R] will have context of [T]
 */
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

/**
 * Checking if [T] is not `null` and if its function completes or satisfies to some condition.
 */
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
    return ifNotNull(this) { it.run(check) } ?: false
}

除了@Benito Bertoli

这种组合实际上与其他组合不同

"test" ?. let {
    println ( "1. it=$it" )
} ?: let {
    println ( "2. it is null!" )
}
结果是:

1. it=test
1. it=test
2. it is null!
1. it is null!
2. it=kotlin.Unit
但如果:

"test" ?. let {
    println ( "1. it=$it" )
    null // finally returns null
} ?: let {
    println ( "2. it is null!" )
}
结果是:

1. it=test
1. it=test
2. it is null!
1. it is null!
2. it=kotlin.Unit
此外,如果先使用elvis:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}
结果是:

1. it=test
1. it=test
2. it is null!
1. it is null!
2. it=kotlin.Unit
Kotlin处理null的方法 安全访问操作

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted
user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}
Let函数

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted
user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}
提前退出

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}
不可变阴影

var user : User? = null

fun handleUser() {
  val user = user ?: return //Return if null, otherwise create immutable shadow
  //Work with a local, non-null variable named user
}
默认值

fun getUserName(): String {
 //If our nullable reference is not null, use it, otherwise use non-null value 
 return userName ?: "Anonymous"
}
使用val而不是var

val
是只读的,
var
是可变的。建议尽可能多地使用只读属性,它们是线程安全的

使用lateinit

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}
有时不能使用不可变的属性。例如,在Android上,当在
onCreate()
call中初始化某些属性时,就会发生这种情况。对于这些情况,Kotlin有一个名为
lateinit
的语言特性

private lateinit var mAdapter: RecyclerAdapter<Transaction>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_transaction)
}

fun updateTransactions() {
   mAdapter.notifyDataSetChanged()
}
private lateinit var mAdapter:RecyclerAdapter
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
mAdapter=回收器适配器(R.layout.item\u事务)
}
趣味updateTransactions(){
mAdapter.notifyDataSetChanged()
}

为什么不使用
if
进行空检查
a?.let{}?:run{}
仅在极少数情况下适用,否则不适用idiomatic@voddan我并不是建议不要对
null
检查使用if,而是列出了其他可行的选项。尽管我不确定
run
是否会有某种性能损失。我将更新我的答案以使其更清楚。@voddan如果
a
var
,那么使用
a?.let{}?:运行{}
可以保证它将在整个范围内正确绑定到
let
。如果
a
val
,则没有区别。@madeinqc如果a是
val
,则使用let是不同的,是不好的。我发现这篇文章非常善于解释-@voddan我对Kotlin是新手。请您解释一下,或者提供一个URL,说明这不是惯用语。请查看链接:-。。。。。。。。。。。。。。在Kotlin文档中很容易,如果我理解正确,那么他是在询问检查Kotlin中null的最佳方法,而不是哪种方法可以生成最佳字节码。@BenitoBertoli的答案看起来很有希望,这是样板代码,我会称最后一个为“默认值”(不是elvis),因为其中三分之四的人使用elvis。@AjahnCharles有道理))这是垃圾,任何现代语言都能更好地处理选项。对程序员来说,这与其说是一种好处,不如说是一件苦差事。