除非明确引用,否则 Kotlin 无法识别参数
Kotlin cannot identify parameters unless explicitly referenced
在尝试用 Kotlin 编写 Android 项目时,有一个问题让我很困惑。
当我尝试调用一些基本的 Android 库函数时,编译器要求提供非常具体的引用。这是一个初始化 LoaderManager 的示例。记下最后一个参数。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loaderManager.initLoader(LOADER_ROUTINE, arguments, this as android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>)
}
这是奇怪的部分。如果我制作一个基于 Java 的 Fragment,在没有冗长或编译器错误的情况下初始化加载程序,然后转换为 Kotlin,则没有错误:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loaderManager.initLoader(88, arguments, this)
}
我错过了什么。 Kotlin 需要什么上下文来防止不得不从第一个示例中添加 as WhateverSpecificClass 的变通方法?
编辑:这是一些额外的上下文。编译时具体错误为:
Type inference failed:
fun <D : Any!> initLoader
(id: Int,
args: Bundle!,
callback: LoaderManager.LoaderCallbacks<D!>!)
: Loader<D!>!
cannot be applied Int,
Bundle!,
EditRoutine
)
片段的整个包装代码
package com.inviscidlabs.ero.Fragments
import android.app.LoaderManager
import android.content.ContentValues
import android.content.Context
import android.content.CursorLoader
import android.content.Loader
import android.database.Cursor
import android.os.Bundle
import android.support.design.widget.TextInputEditText
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import butterknife.BindView
import butterknife.ButterKnife
import com.inviscidlabs.ero.Data.EroProvider
import com.inviscidlabs.ero.Data.Keys
import com.inviscidlabs.ero.Data.Routine
import com.inviscidlabs.ero.R
class EditRoutine : Fragment(), LoaderManager.LoaderCallbacks<Cursor>{
//Values
private val LOADER_ROUTINE: Int = 9150
//Vars
private var mRoutineID: String? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//If the routineID passed is a legitimate ID, initialize the loader
if(!mRoutineID.equals(Keys.m_NullValue)){
// this would not work: loaderManager.initLoader(LOADER_ROUTINE, arguments, this)
loaderManager.initLoader(LOADER_ROUTINE, arguments, this as android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>)
}
}
//Loader Functions
override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor>? {
if(id==LOADER_ROUTINE){
val projection = arrayOf(Routine.Table._ID, Routine.Table.KEY_NAME)
val selection = Routine.Table._ID + "=?"
val selectionArgs = arrayOf(args.getString(Keys.b_RoutineID))
val cL = CursorLoader(activity, //Context
EroProvider.CONTENT_URI_WORKOUT, //URI
projection, //The fields we want (must include ID
selection, //WHERE statement for SQL
selectionArgs, null)//Arguments for WHERE
return cL
}
return null
}
override fun onLoaderReset(loader: Loader<Cursor>?) {
}
override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
上下文参数将简单地从 LoaderCallbacks 接口中使用,因此您将导入其语句并将其作为 class 签名的一部分实现,如下所示:
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.database.Cursor
class WorkSpaceActivity : Fragment(), LoaderManager.LoaderCallbacks<Cursor> {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
loaderManager.initLoader(88, null, this)
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onLoaderReset(loader: Loader<Cursor>?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
在尝试用 Kotlin 编写 Android 项目时,有一个问题让我很困惑。
当我尝试调用一些基本的 Android 库函数时,编译器要求提供非常具体的引用。这是一个初始化 LoaderManager 的示例。记下最后一个参数。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loaderManager.initLoader(LOADER_ROUTINE, arguments, this as android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>)
}
这是奇怪的部分。如果我制作一个基于 Java 的 Fragment,在没有冗长或编译器错误的情况下初始化加载程序,然后转换为 Kotlin,则没有错误:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loaderManager.initLoader(88, arguments, this)
}
我错过了什么。 Kotlin 需要什么上下文来防止不得不从第一个示例中添加 as WhateverSpecificClass 的变通方法?
编辑:这是一些额外的上下文。编译时具体错误为:
Type inference failed:
fun <D : Any!> initLoader
(id: Int,
args: Bundle!,
callback: LoaderManager.LoaderCallbacks<D!>!)
: Loader<D!>!
cannot be applied Int,
Bundle!,
EditRoutine
)
片段的整个包装代码
package com.inviscidlabs.ero.Fragments
import android.app.LoaderManager
import android.content.ContentValues
import android.content.Context
import android.content.CursorLoader
import android.content.Loader
import android.database.Cursor
import android.os.Bundle
import android.support.design.widget.TextInputEditText
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import butterknife.BindView
import butterknife.ButterKnife
import com.inviscidlabs.ero.Data.EroProvider
import com.inviscidlabs.ero.Data.Keys
import com.inviscidlabs.ero.Data.Routine
import com.inviscidlabs.ero.R
class EditRoutine : Fragment(), LoaderManager.LoaderCallbacks<Cursor>{
//Values
private val LOADER_ROUTINE: Int = 9150
//Vars
private var mRoutineID: String? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//If the routineID passed is a legitimate ID, initialize the loader
if(!mRoutineID.equals(Keys.m_NullValue)){
// this would not work: loaderManager.initLoader(LOADER_ROUTINE, arguments, this)
loaderManager.initLoader(LOADER_ROUTINE, arguments, this as android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>)
}
}
//Loader Functions
override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor>? {
if(id==LOADER_ROUTINE){
val projection = arrayOf(Routine.Table._ID, Routine.Table.KEY_NAME)
val selection = Routine.Table._ID + "=?"
val selectionArgs = arrayOf(args.getString(Keys.b_RoutineID))
val cL = CursorLoader(activity, //Context
EroProvider.CONTENT_URI_WORKOUT, //URI
projection, //The fields we want (must include ID
selection, //WHERE statement for SQL
selectionArgs, null)//Arguments for WHERE
return cL
}
return null
}
override fun onLoaderReset(loader: Loader<Cursor>?) {
}
override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
上下文参数将简单地从 LoaderCallbacks 接口中使用,因此您将导入其语句并将其作为 class 签名的一部分实现,如下所示:
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.database.Cursor
class WorkSpaceActivity : Fragment(), LoaderManager.LoaderCallbacks<Cursor> {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
loaderManager.initLoader(88, null, this)
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onLoaderReset(loader: Loader<Cursor>?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}