我想定义一个通用代数数据类型,用于我的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> {
Run Code Online (Sandbox Code Playgroud)
但是,这是不允许的,因为这是T一个未定义的引用.
如果我添加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>()
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这有点令人困惑,这让我相信我在这里遗漏了一些东西.T在第一种情况下定义成员类型时为什么没有看到?
另外,在创建Success我希望语法为的实例时:
Result<T>.Success<T>(tv.someValue, pos)
Run Code Online (Sandbox Code Playgroud)
但这不会起作用而是我这样做:
Result.Success<T>(tv.someValue, pos)
Run Code Online (Sandbox Code Playgroud)
这对我来说是更好的语法,但我很难理解为什么我应该T在这里省略结果.
Result是一个泛型类,有一个名为T的通用参数.Result但是,类名不是Result<T>.
Success也是一个通用类.因此,由于它是通用的,您需要将其定义为Success<T>.如果你不这样做,那么它就不再是通用了.请注意,尽管它是Result的子类,它是通用的,但它可能是非泛型类型.例如:
class Success(val value: String, val pos: Int) : Result<String>()
Run Code Online (Sandbox Code Playgroud)
另请注意,尽管结果和失败是通用的,但它们不会将任何通用类型用于通用类型.所以你实际上可以将你的类定义为
sealed class Result {
class Success<T>(val value: T, val pos: Int) : Result()
class Failure(val message: String, val pos: Int) : Result()
}
Run Code Online (Sandbox Code Playgroud)
现在,你为什么需要使用Result.Success<T>(tv.someValue, pos)而不是Result<T>.Success<T>(tv.someValue, pos)?
因为类的名称是Result.Success.参数类型不是类名的一部分.大多数情况下,没有必要指定它,因为它将被推断:
val r = Result.Success("foo", 1)
Run Code Online (Sandbox Code Playgroud)
创建一个实例Success<String>.如果您想要创建一个Success<CharSequence>,那么您必须明确指定泛型类型:
val r = Result.Success<CharSequence>("foo", 1)
Run Code Online (Sandbox Code Playgroud)
要么
val r: Result.Success<CharSequence> = Result.Success("foo", 1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
590 次 |
| 最近记录: |