新的Kotlin ..与选项和铸造的问题

只是混淆了铸造和如何设置类变量。 在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'是一个可变的属性,可以在这个时候改变

对于Android来说,使用lateinit var是很常见的,因为你在构造函数之外(在onCreate等)创建对象。 你可以走两条路线:

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

我会建议如果你的变量应该可用,当你准备好使用它。 你不需要null检查。 lateinit意味着后期初始化。 Kotlin使用null来表示还没有被初始化,所以你不能使用可为空的类型并在其上赋空值。

如果你的变量是可空的,那么你应该走第二条路。

除此之外,如果你正在处理视图,你应该使用Android扩展来做到这一点。 你不需要在ActivityFragment找到findViewById

这里发生了两件事情。

首先,如@gyosida所指出的那样,你已经将你的mPager属性定义为val而不是var所以它不能在mViewPager = findViewById(R.id.viewpager1)行中重新分配。 正如@Joshua所指出的那样,你必须把它变成一个var或者你需要使它成为一个lateinit val来解决它不被类实例初始化的问题。

第二个是由你描述的实际错误来表示的,“可变属性可以被改变”, 如果你把它变成一个变量 ,你将继续看到这个 使用lateinit方法最有可能是更好的主意。

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

 fun setupViewPager(viewPager: ViewPager): Unit { 

你已经说过viewPager的参数不能为空。 如果是的话,那将是viewPager: ViewPager? 。 所以,如果你传递了一些可能为空的东西,你将会得到一个编译错误。

科特林告诉你的是,在两行之间:

 mViewPager = findViewById(R.id.viewpager1) 

 setupViewPager(mViewPager) 

某事 – 设想另一个线程上的另一个方法 – 可能已经将mViewPager的值从指定的实例更改为null。 所以通过它是不安全的。

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

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