Generics 在泛型函数中访问对象atribute

Generics 在泛型函数中访问对象atribute,generics,kotlin,Generics,Kotlin,如何在泛型函数中访问对象属性?代码,我目前已经声明了错误:未解决的引用:name。我怎样才能让它工作? 有where关键字,但我没有找到太多关于它的信息 fun <T> foo(t:T): String{ return t.name } foo(object { val name = "Foo" }) fun-foo(t:t):字符串{ 返回t.name } foo(对象{ val name=“Foo” }) C++等价物: struct { int n

如何在泛型函数中访问对象属性?代码,我目前已经声明了错误:未解决的引用:name。我怎样才能让它工作? 有
where
关键字,但我没有找到太多关于它的信息

fun <T> foo(t:T): String{
    return t.name
}

foo(object {
    val name = "Foo"
})
fun-foo(t:t):字符串{
返回t.name
}
foo(对象{
val name=“Foo”
})
C++等价物:

struct {
    int name{10};
}a;

template<typename T>
int foo(T&t) {
    return t.name;
}

foo(a);
struct{
int name{10};
}a;
模板
内务主任(电讯及电讯){
返回t.name;
}
傅(甲),;

如果要访问某些特定类型的成员,则应该对类型参数应用上限。 可以这样实施:

fun <T : MyTypeThatHasNameProperty> foo(t: T): String{
    return t.name
}
fun-foo(t:t):字符串{
返回t.name
}

你不能
T
在运行时可以是任何类型的实例。因此您无法访问该属性

不过你可以这样做

fun <T : SomeType> foo(t: T): String {
    return t.name
}

open class SomeType(val name: String)

foo(SomeType("value"))

下面是一个如何在Kotlin中使用反射实现的示例(注意:这里您甚至不需要使用该函数的方式的泛型类型信息):

实际上并不需要使用。你当然可以做完全不同的事情。只是想展示一下在科特林的情况

我在评论中说了一些
具体化的
类型,但实际上这里不需要它

解决您的问题的最大问题是,您有一个匿名类型,这基本上缩小了可能的解决方案的范围,仅“使用反射”;-)

如果您有如下类型/接口:

interface Nameable {
  val name : String
}
然后您可以将
foo
方法更改为:

fun foo(t : Nameable) = t.name
并称之为,将导致:

foo(object : Nameable {
  override val name = "Foo"
}

但是,它不是一个C++模板,如果你想完全动态,你必须创建许多合适的接口,并且在创建匿名类型时必须使用它们。pp.

如果你在泛型中使用Kotlin,这是可能的

foo(object {
    val name = "Foo"
})


inline fun <reified T> foo(t: T): String =
    T::class.declaredMembers.find { it.name == "name" }!!
    .call(t) as String
第三个选项是为您提供通用参数的上限:

foo( NameProvider {
    val name = "Foo"
})

interface NameProvider {
    val name: String
}

fun <T: NameProvider> foo(t: T): String = t.name
foo(名称提供者){
val name=“Foo”
})
接口名称提供程序{
val名称:String
}
fun-foo(t:t):String=t.name


我不知道哪里有
关键字。。。什么意思?注意:泛型类型信息在运行时会被擦除,因此请将其视为您刚刚编写了
t:Any
。显然,您无法访问
任何.name
,因为它不存在。。。您可以通过反射来访问它…注意:如果您不需要支持通过
对象{val name:String}
创建的对象,那么显示的两个答案可能已经满足您的需要。如果您需要更多,您需要采取反射路线。kotlin中的“泛型”是否与Java中的泛型相同?基本上是的,因为它是一样的;-)但在Kotlin,你也可以使用。我刚开始使用这个语言,我觉得它和java一样:D:给定的示例<代码>对象{Valame=“Fo”}< /Cord>这将不起作用……C++中,你已经使用模板完成了,所以创建了一个特定的类型,它有代码> name < /Cord>字段。在对象表达式的情况下,精确类型是匿名的,因为它只是“一次性的”。如果需要一些特定的成员,则应该提供一些特定的类型作为边界。在C++示例中,这是相同的,可能我对C++是不对的:我不具备这种语言的资格。但据我所知,在给定的示例
对象{val name=“Foo”}
中使用了一个指针,这将不起作用,但是…@Roland是的,这就是我提供替代方法的原因。查看更新的答案。您的alteranet aproach在all@majkrzak老实说,我认为在您的情况下根本不需要使用泛型。可能使用
接口
而不是
抽象
类型:
接口可命名{val name:String}
使用refelection似乎是有害的,因为它是运行时的东西,绝对不需要我知道。。。你知道吗?其实不一样,但它可能会帮你解决你的问题?这可能是我需要的让我们看看,不是它需要所有astaff先验的定义是的。。。这是必需的。。。也许是给你的?(不过,您至少需要一个基本类型,其他人都可以从中进行扩展…或者(再次)使用反射:-P)。。。当然。。。它仍然不是等效的,但可能有助于解决问题;-)
foo(object {
    val name = "Foo"
})


inline fun <reified T> foo(t: T): String =
    T::class.declaredMembers.find { it.name == "name" }!!
    .call(t) as String
fun <T: Any> foo(t: T): String =
    t::class.declaredMembers.find { it.name == "name" }!!.call(t) as String
foo( NameProvider {
    val name = "Foo"
})

interface NameProvider {
    val name: String
}

fun <T: NameProvider> foo(t: T): String = t.name