Denoting a universal function of its type, without passing an example of this type

I create a universal function for processing Firebase snapshots, and I found that the general function does not know what type to work with unless you explicitly specify the type by passing it to the argument.

So, I resorted to a really ugly approach by simply creating an empty one, for example, User () and feeding it into this function and never touching it again.

What is the best way to do this?

   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
   }
+4
source share
2 answers

Pass a type object instead of a type instance. Also, andUID:bad style.

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
}

Using:

// Explicit type declaration is unnecessary but included for clarity.
let doodads: [Doodad]? = handleSnapshot(snapshot, forType: Doodad.self)

UPDATE

Another approach: add a method to the FirebaseTypeprotocol extension:

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
    }
}

Using:

let doodads = Doodad.arrayFromSnapshot(snapshot)
+3
source

.

:

protocol Bar {
    init(a: Int)
}

func foo<T: Bar>(arg1: Int) -> T {
    return T(a: arg1)
}

T, ( , Bar).

, , , , :

let x: Baz = foo(3)

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)

'T'

, :

func ambiguous(arg: Int) -> Int {
    return arg
}

func ambiguous(arg: Int) -> Double {
    return Double(arg)
}

let value = ambiguous(2)

""

( ), , .

+3

Source: https://habr.com/ru/post/1629485/


All Articles