gpt4 book ai didi

swift - 使用符合协议(protocol)的类型变量调用泛型函数

转载 作者:行者123 更新时间:2023-11-28 08:06:23 48 4
gpt4 key购买 nike

在泛型函数中,我想测试符合特定协议(protocol)的给定对象是否属于给定类型。如果将具体类类型作为参数传递给检查函数,效果会很好。但是,当我为类型使用变量时(使用三元运算符),出现错误:

Cannot invoke 'isObject' with an argument list of type '(AnyObject, of: P.Type)'

另外将类型变量转换为 P.Protocol 也无济于事,因为:

In argument type 'P.Protocol', 'P' does not conform to expected type 'P'

protocol P {
static var descr: String {get}
}

class A: P {
static let descr = "class A"
}

class B: P {
static let descr = "class B"
}

class Test {
func isObject<T:P>(_ object: AnyObject, of type: T.Type) -> Bool {
print("descr: \(type.descr)")
return object is T
}
}

let a = A()
let type = (false ? A.self : B.self) as P.Type //as! P.Protocol
let test = Test()

test.isObject(a, of: type)

最佳答案

问题在于,对于通用占位符 T,当 T 是协议(protocol)类型 P 时,T.TypeP.Protocol 不是 P.Type。换句话说,它采用描述协议(protocol)本身 的元类型,而不是描述符合协议(protocol)的类型的元类型。这种区别很重要,因为 protocols don't conform to themselves .

您的情况的一个解决方案是围绕 P.Type 元类型引入一个包装器,该元类型在初始化程序中使用通用占位符以存储闭包以执行 is 为你检查。

struct AnyPType {

let base: P.Type
private let _isInstance: (Any) -> Bool

/// Creates a new AnyType wrapper from a given metatype.
/// The passed metatype's value **must** match its static value, i.e `T.self == base`.
init<T : P>(_ base: T.Type) {
precondition(T.self == base, "The static value \(T.self) and dynamic value \(base) of the passed metatype do not match")
self.base = T.self
self._isInstance = { $0 is T }
}

func isInstance(_ instance: Any) -> Bool {
return _isInstance(instance)
}
}

这是我在回答 to this Q&A 中展示的包装器的特殊版本,其中我还展示了如何在 Apple 平台上解除 T.self == base 的限制(但这种限制在您的情况下应该不是问题)。

您现在可以像这样使用包装器:

class Test {
func isObject(_ object: Any, of type: AnyPType) -> Bool {
print("descr: \(type.base.descr)")
return type.isInstance(object)
}
}

let type = AnyPType(A.self) // or AnyPType(B.self)

print(Test().isObject(A(), of: type))

// descr: class A
// true

关于swift - 使用符合协议(protocol)的类型变量调用泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44983480/

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