我想检查泛型类型是否符合协议。如果是的话,我需要转换类型本身并针对它调用一个静态方法。
func log<T>(object: T) {
if let C = T as? Loggable { // this line doesn't compile
print("\(C.description(of: object))")
} else {
print("\(object)")
}
}有人知道这是否可行吗?
更新
我把你和我的第一个代码片段搞混了。希望第二点更有意义。由于@portella的回答,我做了一些改变,但仍然不够。
func decodeObject<T>() -> T? {
guard let object = objects.first else {
return nil
}
objects.removeFirst()
if object is NSNull {
return nil
}
if T.self is Coding.Type { // the condition is fixed, thanks to @Hiron
if let data = object as? Data {
return type(of: (T.self as! Coding)).from(data: data) as? T
} else {
return nil
}
}
return object as? T
}发布于 2016-12-29 09:43:26
假设您有一个带有静态方法的协议和一个实现它的类:
protocol Something {
static func doSomething()
}
class SomethingConcrete: Something {
static func doSomething() {
// does something concrete
}
}还有一个通用函数。如果它获得了Something类型,它就调用它的静态方法(不涉及对象)。
有两种方法可以做到这一点:超载和铸造。
重载(@portella的信用卡)
func someFunction<T: Something>() {
T.doSomething()
}
func someFunction<T>() {
// does something else
}强制铸造(使用@Hiron中提到的类型检查)
func someFunction<T>() {
if T.self is Something.Type {
(T.self as! Something.Type).doSomething()
} else {
// does something else
}
}发布于 2016-12-27 00:11:38
这是否符合你的需要:
protocol Loggable {
func log()
static func staticLog()
}
func log<L: Loggable>(object: L) {
object.log()
L.staticLog()
}您确保发送到函数中的所有对象都符合协议Loggable。
对我来说,我不喜欢这样,但希望下面的解决方案能有所帮助(我强烈推荐第一个解决方案):
protocol Loggable {
func log()
static func staticLog()
}
func log<L>(object: L) {
guard let loggableObject = object as? Loggable else {
print(" Not a loggable object")
return
}
loggableObject.log()
type(of: loggableObject).staticLog()
}
final class NotLoggableClass {}
final class LoggableClass: Loggable {
func log() {
print("")
}
static func staticLog() {
print("")
}
}
log(object: NotLoggableClass())
log(object: LoggableClass())调用log(object: NotLoggableClass())将返回:Not a loggable object
调用log(object: LoggableClass())将返回:
编辑:关于更新,您要检查参数类型还是参数类型?您没有将任何参数发送到您的函数中,这似乎很奇怪。我想你会想要验证它,而不是返回,我想。这就是你想要达到的目标吗?
protocol Coding {
associatedtype T
static func decodeObject<T>(data: Data) -> T?
}
extension UIImage: Coding {
typealias T = UIImage
static func decodeObject<T>(data: Data) -> T? {
return UIImage(data: data) as? T
}
}关于您的解决方案,我不明白objects是从哪里来的。如果希望泛型类型符合Coding protocol,则可以在函数声明中使用约束进行操作。
示例:
protocol Coding {
associatedtype T
static func from(data: Data) -> T?
}
func decodeObject<T: Coding>(_ objects: [Data]) -> T? {
guard let object = objects.first else {
return nil
}
var objects = objects
objects.removeFirst()
return T.from(data: object) as? T
}
extension String: Coding {
static func from(data: Data) -> String? {
return String(data: data, encoding: .utf8)
}
}虽然,我不明白这些对象,但这应该是由类型本身来完成的,而不是由一个普通的助手或其他东西来完成,这在我看来是您正在尝试的。
尽量避免使用Swift进行动态转换和打字
希望这有帮助
发布于 2016-12-27 02:58:15
也许你应该写
if T.self is Coding.Type而不是
if T.self is Codinghttps://stackoverflow.com/questions/41337409
复制相似问题