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
Android 为什么系统显示';智能转换到';文件';是不可能的';在科特林?_Android_Kotlin - Fatal编程技术网

Android 为什么系统显示';智能转换到';文件';是不可能的';在科特林?

Android 为什么系统显示';智能转换到';文件';是不可能的';在科特林?,android,kotlin,Android,Kotlin,在代码A1中,我使用了let语句,因此我认为filenameofVideo.path将不会为空 但我得到以下错误,为什么 智能转换为“File”是不可能的,因为“filenameofVideo”是一个可变属性,此时可能已更改 此时,我必须使用代码A2 代码A1 private var filenameofVideo :File?=null filenameofVideo?.let { Navigation.findNavController(requireActivity(

在代码A1中,我使用了let语句,因此我认为filenameofVideo.path将不会为空

但我得到以下错误,为什么

智能转换为“File”是不可能的,因为“filenameofVideo”是一个可变属性,此时可能已更改

此时,我必须使用代码A2

代码A1

private var filenameofVideo :File?=null

filenameofVideo?.let {
          Navigation.findNavController(requireActivity(), R.id.fragment_container)
               .navigate(UIFragmentCameraDirections.actionCameraToVideo(filenameofVideo.path))
}
   private val aa:String?=null
   aa?.let {
            print(aa)
        }
代码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 var filenameofVideo :File?=null

filenameofVideo?.let {
          Navigation.findNavController(requireActivity(), R.id.fragment_container)
               .navigate(UIFragmentCameraDirections.actionCameraToVideo(filenameofVideo.path))
}
   private val aa:String?=null
   aa?.let {
            print(aa)
        }
代码B2

private val aa:String?=null    
   aa?.let{aa->
           print(aa)
      }
添加内容:

1:在代码C中,var aa可能在?let调用中访问它的那一刻和在let块中访问它的那一刻之间发生了更改(可能由另一个线程更改)

aa不为空时会启动代码C,aa为空时不会启动代码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)
}
代码类似于

private var aa: String? = null
aa?.let {
    print(aa.length)
}
未编译,因为当安全调用
?.let{}
块仅在
aa
属性不为null时执行,当执行达到
aa.length
时,
aa
属性的值可能已在另一个线程中更改为null

另一方面,在本例中

private var aa: String? = null    
aa?.let { aa ->
    print(aa.length)
}
aa
属性的非空值在传递给
let
的lambda的只读
aa
参数中的安全调用后捕获

请注意,使
aa
property
val
代替示例B1中的
var
也有助于消除错误,但这会导致
let
块永远不会执行,因为初始化为null的私有val永远不会变为非null

关于示例C和D之间的区别的附加问题:

  • let{}
    函数的执行方式没有区别。在这两种情况下,lambda函数仅在接收器表达式
    aa
    不为空时启动,因为您使用的是
    ?。
    安全调用运算符
  • 编译器不接受示例D,因为它无法确保lambda中引用的
    aa
    属性的值在执行到达该行时没有更改
    • 代码如下

      private var aa: String? = null
      aa?.let {
          print(aa.length)
      }
      
      未编译,因为当安全调用
      ?.let{}
      块仅在
      aa
      属性不为null时执行,当执行达到
      aa.length
      时,
      aa
      属性的值可能已在另一个线程中更改为null

      另一方面,在本例中

      private var aa: String? = null    
      aa?.let { aa ->
          print(aa.length)
      }
      
      aa
      属性的非空值在传递给
      let
      的lambda的只读
      aa
      参数中的安全调用后捕获

      请注意,使
      aa
      property
      val
      代替示例B1中的
      var
      也有助于消除错误,但这会导致
      let
      块永远不会执行,因为初始化为null的私有val永远不会变为非null

      关于示例C和D之间的区别的附加问题:

      • let{}
        函数的执行方式没有区别。在这两种情况下,lambda函数仅在接收器表达式
        aa
        不为空时启动,因为您使用的是
        ?。
        安全调用运算符
      • 编译器不接受示例D,因为它无法确保lambda中引用的
        aa
        属性的值在执行到达该行时没有更改

      让我们把代码精简一点,以便更容易讨论:

      这里的问题是,即使您调用了
      ?.let
      ,编译器也无法保证
      文件名
      let
      块中不为null。这是因为
      filename
      是一个
      var
      ,并且
      var
      的值可能在
      中被访问的那一刻与在
      let
      块中被访问的那一刻之间发生了更改(可能是通过另一个线程)

      因此,您必须自己处理空值的可能性。最简单的方法是在
      let
      块中使用
      it
      值,或者自己命名该值:

      filename?.let { safe ->
          action(safe.path)
      }
      
      此代码不起作用的原因是:


      这里的变量是
      val
      。这意味着它将是
      null
      或非null,但无论如何都不能更改。因此,您和我可以阅读代码,并看到
      .let
      块将永远不会执行。。。但如果它是,那就意味着
      aa
      保证不为null,因此编译器可以智能地将其转换为不可为null的类型。

      让我们稍微精简一下代码,以便更容易讨论:

      这里的问题是,即使您调用了
      ?.let
      ,编译器也无法保证
      文件名
      let
      块中不为null。这是因为
      filename
      是一个
      var
      ,并且
      var
      的值可能在
      中被访问的那一刻与在
      let
      块中被访问的那一刻之间发生了更改(可能是通过另一个线程)

      因此,您必须自己处理空值的可能性。最简单的方法是在
      let
      块中使用
      it
      值,或者自己命名该值:

      filename?.let { safe ->
          action(safe.path)
      }
      
      此代码不起作用的原因是: