【发布时间】:2026-02-09 20:35:01
【问题描述】:
在设计使用和生成泛型类型的结果构建器时,我经常发现自己需要以一种令人讨厌的显式方式拼写类型。考虑这个玩具示例:
@resultBuilder enum SomeBuilder {
static func buildBlock(_ v: Result<Int,Error>) -> Result<Int,Error> { v }
}
struct SomeStruct {
init(@SomeBuilder _ v: () -> Result<Int,Error>) {}
}
let x = SomeStruct {
Result.success(0)
}
SomeBuilder 几乎是最简单的@resultBuilder:它接受Result<Int,Error> 类型的单个值并按原样返回它们。 SomeStruct 是一个简单的结构体,它带有一个初始化器,它接受一个产生Result<Int,Error> 的@SomeBuilder 闭包。因此,对我来说,应该编译这段代码是有意义的。 Swift 应该能够找出 Result.success(0) 指的是 Result<Int,Error>.success(0) 因为这是唯一在这种情况下有意义的类型。但是,此示例无法编译
_:9:5: error: cannot convert value of type 'Result<Int, _>' to expected argument type 'Result<Int, Error>'
Result.success(0)
^
_:9:5: note: arguments to generic parameter 'Failure' ('_' and 'Error') are expected to be equal
Result.success(0)
^
_:9:5: error: generic parameter 'Failure' could not be inferred
Result.success(0)
^
_:9:5: note: explicitly specify the generic arguments to fix this issue
Result.success(0)
^
<Int, <#Failure: Error#>>
在同一行中,Swift 声称它无法推断出Result.success(0) 的Failure 类型,然后声称它知道失败一定是Error。我可以通过使用来编译这段代码
let x = SomeStruct {
Result<Int,Error>.success(0)
}
但在实际示例中,对类型如此冗长对我要设计的 DSL 极为不利。
这是编译器中的错误吗?如何让 Swift 推断出结果构建器(例如这个)中的泛型类型?
【问题讨论】: