gpt4 book ai didi

swift - 测试实例是否是 Swift 中带有类型别名的协议(protocol)?

转载 作者:搜寻专家 更新时间:2023-10-31 08:33:25 24 4
gpt4 key购买 nike

这与 this question 有关.使用 typealias 我可以创建一个具有“子”var 但具有特定类型的类,这正是我正在寻找的。但是当我这样做时,我无法再测试一个实例是否遵循该协议(protocol)。我也尝试过“if let”,但没有用。有什么办法吗?

protocol Parent {
typealias Child
var children: [Child] { get set }
}

protocol Child {
typealias Parent
var parent: Parent { get set }

}

class Foo: Parent {
var children = [Bar]()

init(){}
}

class Bar: Child {
var parent = Foo()
}

let testVar = Foo()
let cVar = Bar()

testVar.children.append(cVar)
cVar.parent = testVar

//I get the error here saying protocol is limited to generic constraints
if testVar is Parent {

}

最佳答案

不幸的是,没有办法静态地解决这个问题(至少目前是这样)。因此,一种更动态的方法是拥有一个没有自关联类型要求的“ super ”协议(protocol)。这允许您在这些“ super ”协议(protocol)之间进行转换:

protocol _Parent {
var anyChildren: [Any] { get set }
}
protocol Parent: _Parent {
typealias Child
var children: [Child] { get set }
}

extension Parent {
// requirement of _Parent
var anyChildren: [Any] {
get {
return children.map{ $0 as Any }
}
set {
// use `as!` and `map` if you are sure that all elements are of type Child
// or if you want a crash if not
children = newValue.flatMap{ $0 as? Child }
}
}
}

protocol _Child {
var anyParent: Any { get set }
}

protocol Child: _Child {
typealias Parent
var parent: Parent { get set }
}

extension Child {
// requirement of _Child
var anyParent: Any {
get {
return parent
}
set {
parent = newValue as! Parent
}
}
}

现在您可以使用它们的属性来操作数据:

class Foo: Parent {
var children = [Foo]()
}

let anything: Any = Foo()

// use `if let` and `as?` instead of `is` in order to have a more static type
if let aDynamicParent = anything as? _Parent {
aDynamicParent.anyChildren.map{ $0 as! Foo } // cast the array back to its original type

aDynamicParent.children = [Foo(), Foo(), Foo()]
}

关于swift - 测试实例是否是 Swift 中带有类型别名的协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32484317/

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