ReturnType }-6ren">
gpt4 book ai didi

swift - 如何解决 "Protocol ... can only be used as a generic constraint..."

转载 作者:行者123 更新时间:2023-11-28 11:11:29 25 4
gpt4 key购买 nike

考虑这段代码:

public protocol Evaluable {
typealias ReturnType
func eval(s: State) -> ReturnType
}

protocol AlgebraicExpr : Evaluable {
}

public struct Const : AlgebraicExpr {
var value: Int = 0

public func eval(s: State) -> Int {
return value
}
}

public struct Add : AlgebraicExpr {
let a, b: AlgebraicExpr

public func eval(s: State) -> Int {
return a.eval() + b.eval()
}
}

它是无效的,因为 Add 不能有 AlgebraicExpr 变量。

但我确实需要Add 来存储两个AlgebraicExpr。你会如何在 Swift 中解决这个问题?

为了完整起见,State只是一个结构体,例如:

public struct State {
var env = Dictionary<String, Int>()

init(_ d: Dictionary<String, Int> = [:]) {
env = d
}

subscript(s: String) -> Int? {
get {return env[s]}
set {env[s] = newValue}
}
}

最佳答案

您不能存储两个依赖于Selftypealias 的协议(protocol),因为当抽象为协议(protocol)时,功能是不确定的。如果不理解 ReturnType 的值,类型 Evaluable 没有实际意义,因此系统不可能按逻辑运行并理解应该返回什么。

例如这样的事情(无效)

let thing: Evaluable = ...
let result = thing.eval(state) // What should return type be?

不能单独通过协议(protocol)推断返回类型,它需要指定类型的实现,通过定义 typealias ReturnType

提供有关其行为的更多信息

这些可以用作通用约束的原因是可以通过通用参数推断实现。

func genericConstrained<T: Evaluable>(evaluable: T, state: State) -> T.ReturnType {
return evaluable.eval(state)
}

在此示例中,当我们在特定的符合对象上调用 genericConstrained 时,可以推断出它的所有其他功能。

tl;dr

但是,如果您还限制了您的包裹,您可以按照您的意愿做:

public struct Add<ExpressionType : AlgebraicExpr> : AlgebraicExpr {
let a, b: ExpressionType

public func eval(s: State) -> ExpressionType.ReturnType {
return a.eval() + b.eval()
}
}

然后用like

let add: Add<SomeConformingType> = ...

关于swift - 如何解决 "Protocol ... can only be used as a generic constraint...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34755436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com