简体   繁体   中英

How can I determine what is the type of generic parameter type in function in Swift?

I have a protocol and 2 struct that conform to that protocol and I have a function that take a generic (which constraints to protocol). In the function, I have to get some data based on the type of the argument. I try to find a way to do this but I'm still not sure which way is the most suitable for this scenario.

protocol Data {
  var id: String { get }
}

struct File: Data {
  var id: String
  var size: Int
}

struct Folder: Data {
  var id: String
  var color: Int
}

class Observer {}

private var callbacksOfFile: [String: ObserverSet<File>] = [:]
private var callbacksOfFolder: [String: ObserverSet<Folder>] = [:]

func subscribeUpdateForData<T: Data>(data: Data, withCallback callback: (T) -> Void) -> Observer {
  if let file = data as? File, let callbacks = callbacksOfFile[data.id] {
    callbacks.add(callback) // Error
  } else if let folder = data as? Folder, let callbacks = callbacksOfFolder[data.id] {
    callbacks.add(callback) // Error
  }
}

What is the best way to work on this case? Now I use function overloading instead of Generic but I ask you in case there is a better way for this scenario.

Thank you.

You many not need your individual callbackOf{File,Folder} distinction as they are, after all, both subtypes of Data . Perhaps

class Observer {
  var callbacks : [((Data) -> Void)] : []

  func addCallback (callback: (Data) -> Void) {
    callbacks.append(callback)
  }

  func invokeCallbacks () {
    /* ... */
  }
}

If all you need is that different callback code is invoked on File and Folder types, then you do this within your structures. Like this:

protocol Data {
  var id: String { get }
  func processData ();
}

struct File: Data {
  var id: String
  var size: Int

  func processData () {
   /* implement for File */
  }
}

struct Folder: Data {
  var id: String
  var color: Int

  func processData () {
   /* implement for Folder */
  }
}

and then call 'processData()` appropriately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM