Swift 告诉泛型函数其类型而不传递该类型的示例

Swift 告诉泛型函数其类型而不传递该类型的示例,swift,generics,Swift,Generics,我正在创建一个泛型函数来处理Firebase快照,我发现泛型函数不知道使用哪种类型,除非通过在参数中输入它来显式地告诉它该类型 所以我采用了一种非常丑陋的方法,只创建一个空格,例如User(),然后将它输入到这个函数中,再也不碰它了 有什么更好的方法 func handleSnapshot<T: FirebaseType>(snapshot: FDataSnapshot?, forType type: T) -> [T]? { guard let snapsh

我正在创建一个泛型函数来处理Firebase快照,我发现泛型函数不知道使用哪种类型,除非通过在参数中输入它来显式地告诉它该类型

所以我采用了一种非常丑陋的方法,只创建一个空格,例如User(),然后将它输入到这个函数中,再也不碰它了

有什么更好的方法

   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)