generics - 为什么通用代数数据类型需要 `T` 成员类型?

标签 generics kotlin

我想定义一个通用代数数据类型以与我的 parse 函数一起使用,如下所示:

sealed class Result<T> {
    class Success(val value: T, val pos: Int) : Result<T>()
    class Failure(val message: String, val pos: Int) : Result<T>()
}

fun <T> parse(t: Parser<T>, input: String, initialPos: Int = 0, collectErrors: Boolean = true) : Result<T> {

然而,这是不允许的,因为 T 是一个 undefined reference 。

如果我将 T 添加到所有成员类型,它会起作用:
sealed class Result<T> {
    class Success<T>(val value: T, val pos: Int) : Result<T>()
    class Failure<T>(val message: String, val pos: Int) : Result<T>()
}

对我来说,这有点令人困惑,这让我相信我在这里遗漏了一些东西。为什么在第一种情况下定义成员类型时没有看到 T

此外,在创建 Success 实例时,我希望语法为:
Result<T>.Success<T>(tv.someValue, pos)

但这行不通,我这样做:
Result.Success<T>(tv.someValue, pos)

这对我来说是更可取的语法,但我很难理解为什么我应该在这里省略 Result 上的 T

最佳答案

Result 是一个泛型类,有一个名为 T 的泛型参数。不过类名是 Result ,而不是 Result<T>
Success 也是一个泛型类。因此,由于它是通用的,您需要将其定义为 Success<T> 。如果你不这样做,那么它就不再是通用的了。请注意,即使它是泛型 Result 的子类,它也可能是非泛型类型。例如:

class Success(val value: String, val pos: Int) : Result<String>()

还要注意,虽然 Result 和 Failure 是通用的,但它们不会将它们的通用类型用于任何事情。所以你实际上可以将你的类定义为
sealed class Result {
    class Success<T>(val value: T, val pos: Int) : Result()
    class Failure(val message: String, val pos: Int) : Result()
}

现在,为什么需要使用 Result.Success<T>(tv.someValue, pos) 而不是 Result<T>.Success<T>(tv.someValue, pos)

因为类的名称是 Result.Success 。参数类型不是类名的一部分。大多数时候,根本没有必要指定它,因为它会被推断:
val r = Result.Success("foo", 1)

创建 Success<String> 的一个实例。如果你想创建一个 Success<CharSequence> ,那么你必须明确指定泛型类型:
val r = Result.Success<CharSequence>("foo", 1)

或者
val r: Result.Success<CharSequence> = Result.Success("foo", 1)

关于generics - 为什么通用代数数据类型需要 `T` 成员类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38029391/

相关文章:

java - 如何限制自引用类型?

c# - C# 3.0 中 "special class"枚举的泛型类型约束是否有解决方法?

Java 泛型 : Collections. max() 签名和比较器

kotlin - 如何模拟调用 kotlin.system.exitProcess

c++ - 为什么 Boost Graph Library 的 `source()` 是一个全局函数?

swift - 如何使用类型为 "Cannot invoke ' 的参数列表修复 '(eventStore: EventStoring)' createEvent'

android - 在 RecyclerView.Adapter 中绑定(bind) View 时出现 NullPointerException

android - 如果我想在滑动后调用操作,如何在 Compose 中实现滑动

spring-boot - Spring 注释在Kotlin中不起作用

android - 如何防止Android SpeechRecognizer被破坏后发出声音?