【问题标题】:New to Kotlin..having issues with Optionals and CastingKotlin 新手.. 遇到 Optionals 和 Casting 问题
【发布时间】:2017-09-22 23:18:25
【问题描述】:

只是对强制转换和如何设置类变量感到困惑。在java中可以这样做

private var mSectionsStatePageAdapter : SectionsStatePagerAdapter? = null
private val mViewPager : ViewPager? = null

现在我们在 kotlin

class MainActivity : AppCompatActivity() {
   private var mSectionsStatePageAdapter : SectionsStatePagerAdapter? = null
   private val mViewPager : ViewPager? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val mytoolbar:Toolbar = findViewById(R.id.top_toolbar)
    setSupportActionBar(mytoolbar)

    mSectionsStatePageAdapter =  SectionsStatePagerAdapter(getSupportFragmentManager())
    mViewPager = findViewById(R.id.viewpager1)


    setupViewPager(mViewPager)
}



 fun setupViewPager(viewPager :ViewPager):Unit {
        var adapter : SectionsStatePagerAdapter = SectionsStatePagerAdapter(getSupportFragmentManager())
        adapter.addFragment(Fragment1(),"Fragment1")
        viewPager.setAdapter(adapter)
    }

我得到 val 无法重新分配... 错误:(65, 24) 智能投射到“ViewPager!”是不可能的,因为 'mViewPager' 是一个可变属性,此时可能已更改

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    对于 Android,通常使用 lateinit var,因为您在构造函数之外创建对象(在 onCreate 等中)。你可以走两条路线:

    • lateinit var variable:Type
    • var variable:Type?

    我建议您的变量在准备好使用时是否可用。你不需要做null检查。 lateinit 表示延迟初始化。 Kotlin 使用null 表示尚未初始化,因此不能使用可空类型并对其赋值。

    如果您的变量可以为空,那么您应该采用第二种方式。

    此外,如果您正在处理视图,则应使用Android extension 来执行此操作。您不需要自己在ActivityFragmentfindViewById

    【讨论】:

      【解决方案2】:

      这里发生了两件事。

      首先,正如@gyosida 指出的那样,您已将mPager 属性定义为val 而不是var,因此无法在mViewPager = findViewById(R.id.viewpager1) 行中重新分配它。正如@Joshua 指出的那样,您要么必须将其设为var,要么将其设为lateinit val 以解决它没有被类实例初始化的问题。

      第二个由您描述的实际错误表示,“可能已更改的可变属性”,如果您将其设为 var,您将继续看到此错误。使用方法lateinit 很可能是更好的主意。

      但是,为了解释这个错误,在你的方法声明中:

      fun setupViewPager(viewPager: ViewPager): Unit {
      

      您说过viewPager 的参数不能为空。如果是,那就是viewPager: ViewPager?。所以,如果你传入一些可能为 null 的东西,你会得到一个编译错误。

      Kotlin 告诉你的是字里行间:

      mViewPager = findViewById(R.id.viewpager1)
      

      setupViewPager(mViewPager)
      

      某些东西 - 想象另一个线程上的另一个方法 - 可能已经将 mViewPager 的值从分配的实例更改为 null。所以传入是不安全的。

      在不改变方法的情况下解决这个问题的唯一方法是提供一个保证为非空的值。有几种方法可以做到这一点:

      • 将您的值分配给不受干扰的方法级变量,并将其作为参数提供
      • 只调用你的函数如果值是非空的,例如mViewPager?.let{ pager -> setupViewPager(pager)}
      • 断言mViewPager 不会为空,任何违规都会在运行时失败,例如setupViewPager(mViewPager!!)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 1970-01-01
        • 2018-09-13
        • 2012-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多