gpt4 book ai didi

swift - 是否可以从通用函数返回符合协议(protocol) A 或协议(protocol) B 的对象?

转载 作者:搜寻专家 更新时间:2023-11-01 06:10:32 24 4
gpt4 key购买 nike

像这样:

protocol A {}
protocol B {}

func newObject<T: A, B>(flag: Bool) -> T {
if flag {
var aaa: A
return aaa
} else {
var bbb: B
return bbb
}
}

我收到一个错误:

'A' is not convertible to 'T'

最佳答案

您正在寻找的类型称为“Either”,它可以使用枚举在 Swift 中轻松创建。例如:

protocol A {}
protocol B {}

enum AorB {
case IsA(A)
case IsB(B)
}

func newObject(flag: Bool) -> AorB {
if flag {
return .IsA(...create an A...)
} else {
return .IsB(...create a B...)
}
}

当创建这样的东西时,您应该非常仔细地考虑您的类型的真正含义。什么是 AorB真的吗?可以通过创建 Either<Left,Right> 来为此创建一个通用支架(这在某些语言中很常见),但在许多情况下,这个枚举有更好的名称(如 SuccessFailureLocalRemote )。当您的类型阅读清晰时,您的程序更有可能是正确的。


请注意,Swift 确实支持返回重载。例如:

typealias A = String
typealias B = Int

func newObject() -> A {
return "a"
}

func newObject() -> B {
return 1
}

let x:A = newObject()

然而,这应该小心使用,因为它对调用者来说可能很尴尬(当然,传递标志也是如此……)。对于可能以使类型推断起作用的方式链接的函数,它更有意义。在我看来,如果你有一个在两种行为之间切换的 bool 值,那么你真正拥有的是两个函数,你应该强烈倾向于给它们命名不同的东西。


这是一个完整的工作示例。不幸的Box type 是 Beta5 的解决方法。编译器尚未实现在枚举中存储任意大小的通用对象的能力。它必须在编译时知道大小。所以我们用 Box 得到它,它的大小已知,因为它只包含一个 []。 (这对我们来说才是真正的拳击)。通过 Swift 的 v1,你应该能够放弃 Box完全包装。

protocol A {
class func create() -> Self
}

class SomethingA : A {
class func create() -> SomethingA { println("making A"); return SomethingA() }
}

protocol B {
class func instantiate() -> Self
}

class SomethingB : B {
class func instantiate() -> SomethingB { println("making B"); return SomethingB() }
}

// Box is because of unimplemented compiler features in beta 5.
struct Box<A> {
private let box: [A]
init(_ value: A) { self.box = [value] }
var value:A { return self.box[0] }
}

enum Either<L,R> {
case Left(Box<L>)
case Right(Box<R>)
}

func newObject<L: A, R: B>(flag: Bool) -> Either<L,R> {
if flag {
return .Left(Box(L.create()))
} else {
return .Right(Box(R.instantiate()))
}
}


let x:Either<SomethingA,SomethingB> = newObject(true)

switch x {
case .Left(let a): println("I have a: ", a.value, a.value)
case .Right(let b): println("I have b:", b.value)
}

关于swift - 是否可以从通用函数返回符合协议(protocol) A 或协议(protocol) B 的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25203050/

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