Swift 告诉泛型函数其类型而不传递该类型的示例
我正在创建一个泛型函数来处理Firebase快照,我发现泛型函数不知道使用哪种类型,除非通过在参数中输入它来显式地告诉它该类型 所以我采用了一种非常丑陋的方法,只创建一个空格,例如User(),然后将它输入到这个函数中,再也不碰它了 有什么更好的方法Swift 告诉泛型函数其类型而不传递该类型的示例,swift,generics,Swift,Generics,我正在创建一个泛型函数来处理Firebase快照,我发现泛型函数不知道使用哪种类型,除非通过在参数中输入它来显式地告诉它该类型 所以我采用了一种非常丑陋的方法,只创建一个空格,例如User(),然后将它输入到这个函数中,再也不碰它了 有什么更好的方法 func handleSnapshot<T: FirebaseType>(snapshot: FDataSnapshot?, forType type: T) -> [T]? { guard let snapsh
func handleSnapshot<T: FirebaseType>(snapshot: FDataSnapshot?, forType type: T) -> [T]? {
guard let snapshot = snapshot, dictionaries = snapshot.value as? [NSObject: AnyObject] else { return nil }
var objects = [T]()
for (uid, dictionary) in dictionaries {
let theUID = uid as? String ?? "No UID"
guard let dictionary = dictionary as? [NSObject: AnyObject] else { return nil }
let object = T(fromDictionary: dictionary, andUID: theUID)
objects.append(object)
}
return objects
}
func handleSnapshot(快照:FDataSnapshot?,forType类型:T)->[T]?{
guard let snapshot=snapshot,dictionaries=snapshot.value为?[NSObject:AnyObject]else{return nil}
变量对象=[T]()
用于字典中的(uid,字典){
让uid=uid作为字符串??“无uid”
guard let dictionary=字典为?[NSObject:AnyObject]else{return nil}
让object=T(fromDictionary:dictionary和uid:theUID)
objects.append(对象)
}
返回对象
}
传递类型对象,而不是类型的实例。而且,和uid:
是不好的风格
func handleSnapshot<T: FirebaseType>(snapshot: FDataSnapshot?, forType type: T.Type) -> [T]? {
guard let snapshot = snapshot, dictionaries = snapshot.value as? [NSObject: AnyObject] else { return nil }
var objects = [T]()
for (uid, dictionary) in dictionaries {
let theUID = uid as? String ?? "No UID"
guard let dictionary = dictionary as? [NSObject: AnyObject] else { return nil }
if let object = T(fromDictionary: dictionary, uid: theUID) {
objects.append(object)
}
}
return objects
}
更新
另一种方法:将该方法添加到协议扩展中的FirebaseType
:
extension FirebaseType {
func arrayFromSnapshot(snapshot: FDataSnapshot?) -> [Self]? {
guard let snapshot = snapshot, dictionaries = snapshot.value as? [NSObject: AnyObject] else { return nil }
var objects = [Self]()
for (uid, dictionary) in dictionaries {
let theUID = uid as? String ?? "No UID"
guard let dictionary = dictionary as? [NSObject: AnyObject] else { return nil }
if let object = Self(fromDictionary: dictionary, uid: theUID) {
objects.append(object)
}
}
return objects
}
}
使用:
根据上下文,可以推断泛型的类型 考虑以下简化示例:
protocol Bar {
init(a: Int)
}
func foo<T: Bar>(arg1: Int) -> T {
return T(a: arg1)
}
我们甚至可以使用cast语法:
let y = foo(3) as Baz
或者,如果我们有一个带有显式类型参数的函数,并且我们正在进行此方法调用:
func printIt(value: Baz) {
print(value)
}
printIt(foo(5))
或者,如果我们有一个具有显式类型的属性的类,我们正在设置:
class Z {
var value: Baz
init(arg: Baz) {
value = arg
}
}
let z = Z(arg: Baz(a: 0))
z.value = foo(4)
重要的是,如果你必须有一些方法来确定这些信息
还值得注意的是,尽管确切的错误消息不同,但我们在这里看到的错误是:
func generic<T: Bar>(arg: Int) -> T {
return T(a: arg)
}
let f = generic(2)
“歧义”的歧义用法
尽管错误消息不同(因为来源根本不同),但问题是完全相同的,两个问题的解决方案是相同的。这稍微好一点,但最终,您仍然会告诉它类型。除了告诉它或让它读懂您的想法之外,还有什么其他方式可以让它知道您想要的类型?严肃的问题。我发布了一些解决方案。我还对你的答案投了更高的票,因为它肯定比问题中的解决方案好。我添加了另一个解决方案。
func printIt(value: Baz) {
print(value)
}
printIt(foo(5))
class Z {
var value: Baz
init(arg: Baz) {
value = arg
}
}
let z = Z(arg: Baz(a: 0))
z.value = foo(4)
func generic<T: Bar>(arg: Int) -> T {
return T(a: arg)
}
let f = generic(2)
func ambiguous(arg: Int) -> Int {
return arg
}
func ambiguous(arg: Int) -> Double {
return Double(arg)
}
let value = ambiguous(2)