在代码A1中,我使用了let
语句,所以我认为filenameofVideo.path
不会为空
但是我得到以下错误,为什么?
不可能将其强制转换为“文件”,因为“ filenameofVideo”是可变的属性,这一次可能已经更改了
此刻,我必须使用代码A2。
代码A1
private var filenameofVideo :File?=null
filenameofVideo?.let {
Navigation.findNavController(requireActivity(), R.id.fragment_container)
.navigate(UIFragmentCameraDirections.actionCameraToVideo(filenameofVideo.path))
}
代码A2
private var filenameofVideo :File?=null
filenameofVideo?.let {filenameofVideo ->
Navigation.findNavController(requireActivity(), R.id.fragment_container)
.navigate(UIFragmentCameraDirections.actionCameraToVideo(filenameofVideo.path))
}
还有,我发现代码B1和代码B2都是正确的。为什么代码B1正确而代码A1错误?
代码B1
private val aa:String?=null
aa?.let {
print(aa)
}
代码B2
private val aa:String?=null
aa?.let{aa->
print(aa)
}
添加的内容:
1:在代码C中,在?.let调用中访问它的时刻与在let块中访问它的时刻之间,var aa可能已被更改(也许被另一个线程)。
aa不为null时将启动代码C,而aa为null时将不启动代码C,对吗?
2:在代码D中(我假设编译器会接受它),无论aa是否为null,该函数始终会启动,无法接受,因此系统会中断,对吗?
代码C
private var aa: String? = null
aa?.let { kk ->
print(kk.length)
}
代码D
private var aa: String? = null
aa?.let {
print(aa.length)
}
答案 0 :(得分:2)
让我们简化一下代码,以便于讨论:
private var filename :File?=null filename?.let { action(filename.path) }
这里的问题是,即使您已调用?.let
,编译器也不能保证filename
块内的let
不为null。这是因为filename
是var
,并且在var
调用中访问?.let
的值之间可能已更改(也许是由另一个线程)以及在let
块中对其进行访问的时间。
因此,您必须自行处理null的可能性。最简单的方法是使用it
块内的let
值,或自己命名该值:
filename?.let { safe ->
action(safe.path)
}
此代码有效的原因:
private val aa:String?=null aa?.let { print(aa) }
是这里的变量是val
。这意味着它将为null
或为非null,但无论哪种方式它都不会改变。因此,您和我可以阅读代码,并看到.let
块将永远不会执行...但是,如果以某种方式 了,那意味着aa
可以保证不为null,因此编译器可以将其智能转换为不可为null的类型。
答案 1 :(得分:1)
类似的代码
private var aa: String? = null
aa?.let {
print(aa.length)
}
之所以无法编译,是因为尽管仅在?.let { }
属性不为null的情况下执行安全调用aa
块,但在执行达到aa.length
时,{{1 }}属性可能已在另一个线程中更改为null。
另一方面,在此示例中
aa
安全调用之后,在传递给{{1}的lambda的只读private var aa: String? = null
aa?.let { aa ->
print(aa.length)
}
参数中捕获了aa
属性的非null值。
请注意,使aa
属性为let
而不是示例中的aa
可以帮助消除错误,但这会导致val
块从不执行初始化为null的私有val永远不会变为非null。
关于示例C和示例D有什么区别的另一个问题:
var
函数的执行方式没有什么不同。在这两种情况下,仅当接收方表达式let
不为null时才启动lambda函数,因为您使用了let { }
安全调用运算符。aa
属性的值未更改。