类型推断失败:没有足够的信息来推断参数,请明确指定 [英] Type inference failed: Not enough information to infer parameter Please specify it explicitly
问题描述
我正在尝试用Kotlin编写Vaadin应用程序.对于数据绑定,Vaadin 8现在提供了类型安全数据绑定的可能性.在Kotlin中,我期望这样的工作:
I'm trying to write a Vaadin application in Kotlin. For data binding, Vaadin 8 now provides a possibility for type safe data binding. In Kotlin I would have expected work like that:
class LoginModel {
var username: String = ""
var password: String = ""
}
class LoginView : FormLayout() {
val name = TextField("name")
val password = TextField("password")
val loginButton = Button("login")
init {
val binder = Binder<LoginModel>()
binder.forField(name).bind(
{ it.username },
{ bean, value -> bean.username = value })
//...
}
}
我在这里收到以下错误消息:
I'm getting the following error message here:
Error:(23, 31) Kotlin: Type inference failed: Not enough information to infer parameter BEAN in fun <BEAN : Any!, TARGET : Any!, BEAN : Any!> Binder.BindingBuilder<BEAN#1 (type parameter of bind), TARGET>.bind(p0: ((BEAN#1!) -> TARGET!)!, p1: ((BEAN#1!, TARGET!) -> Unit)!): Binder.Binding<BEAN#1!, TARGET!>!
Please specify it explicitly.
我通过显式指定类型参数来尝试:
I tried by explicit specifying the type parameters:
binder.forField(name).bind<LoginView, String, LoginView>(
{ it.username },
{ bean, value -> bean.username = value })
但这会导致错误消息(以及其他语法错误,因此我没有遵循该方法)
but that leads to the error message (and other sytax errors, so I did not follow that approach)
Error:(23, 35) Kotlin: No type arguments expected for fun bind(p0: ValueProvider<LoginModel!, String!>!, p1: Setter<LoginModel!, String!>!): Binder.Binding<LoginModel!, String!>! defined in com.vaadin.data.Binder.BindingBuilder
我的第二种方法是尝试直接传递Kotlin属性访问器,但是错误消息与第一种相同:
My second approach was trying to pass the Kotlin property accessors directly, but the error message was the same as the first one:
binder.forField(name).bind(LoginModel::username.getter, LoginModel::username.setter)
最后一种方法是尝试使用扩展方法并使所有内容尽可能明确:
The last approeach was trying to use an extension method and make everything as explicit as possible:
fun <BEAN, TARGET> Binder.BindingBuilder<BEAN, TARGET>.bind(property: KMutableProperty1<BEAN, TARGET>) {
fun set(bean: BEAN): TARGET = property.get(bean)
fun get(bean: BEAN, value: TARGET): Unit = property.set(bean, value)
this.bind(::set, ::get)
}
但是它仍然导致与第一个相同的错误消息
But it leads still to the same error message as the first one
推荐答案
我已经尝试了您的示例,并且使用我的Intellij 2017.1.4和Kotlin 1.1.2-5可以很好地进行编译.可能是您发现了较旧版本的Kotlin插件中的错误?
I have tried your example and it compiles just fine with my Intellij 2017.1.4 and Kotlin 1.1.2-5. Probably you have discovered a bug in older version of a Kotlin plugin?
方法bind
不使用通用参数,因此无法泛化. forField
方法采用一个通用参数,因此也许您可以尝试
The method bind
takes no generic parameters so it cannot be generified. The forField
method takes one generic parameter, so perhaps you can try
binder.forField<String>(name).bind(
{ it.username },
{ bean, value -> bean.username = value })
但是首先,请确保您具有最新版本的Kotlin插件,和/或尝试使用Intellij Community Edition进行试用.
But first, please make sure that you have the newest version of the Kotlin plugin, and/or perhaps try it out with Intellij Community Edition.
但是,我建议您使用bind(String)
,因为其他绑定方法不适用于JSR303验证.您还可以定义以下扩展方法:
However, I urge you to use bind(String)
since other bind methods won't work with JSR303 validations. You can also define the following extension method:
fun <BEAN, FIELDVALUE> Binder.BindingBuilder<BEAN, FIELDVALUE>.bind(prop: KMutableProperty1<BEAN, FIELDVALUE?>): Binder.Binding<BEAN, FIELDVALUE> =
bind(prop.name)
并从您的代码binder.forField(name).bind(LoginModel::username)
中进行如下调用.请在此处查看更多示例:
And call it as follows from your code binder.forField(name).bind(LoginModel::username)
. Please see here for more examples: https://github.com/mvysny/karibu-dsl/blob/master/example-v8/src/main/kotlin/com/github/vok/karibudsl/example/form/FormView.kt
这篇关于类型推断失败:没有足够的信息来推断参数,请明确指定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!