确定 Any.Type 是否可选
Determine if Any.Type is Optional
我正在尝试确定给定类型 t
(Any.Type
) 是否为可选类型,我正在使用此测试
t is Optional<Any>.Type
但它 returns 总是错误的。
那么有什么办法可以实现吗?
您可以使用泛型来实现:
func isOptional<T>(x:T?)->Bool
{
return true
}
func isOptional<T>(x:T)->Bool
{
return false
}
编辑
上面的代码可以用来判断一个变量是否是可选类型。
我想出了解变量 包含 类型的唯一方法是使用反射:
var t1:Any.Type=(String?).self
var t2:Any.Type=(String).self
Mirror(reflecting: t1).description
Mirror(reflecting: t2).description
第一次调用 Mirror 给出字符串 "Mirror for Optional<String>.Type"
,第二次调用给出 "Mirror for String.Type"
.
我知道比较字符串不是进行此检查的便捷方法,我会再次尝试找到性能更高的东西..
假设您正在尝试做的是这样的事情:
let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false
遗憾的是 swift 目前(从 Swift 2 开始)不支持 covariance nor contravariance 并且无法直接针对 Optional.Type
进行类型检查:
// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error
另一种方法是 Optional
扩展特定协议,并检查该类型:
protocol OptionalProtocol {}
extension Optional : OptionalProtocol {}
let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true
聚会有点晚了。但是,我运行陷入了同样的问题。这是我的代码。
func isOptional(_ instance: Any) -> Bool {
let mirror = Mirror(reflecting: instance)
let style = mirror.displayStyle
return style == .optional
}
let a: Int = 1 // false
let b: Int? = 2 // true
let c: Double = 3.0 // false
let d: Double? = 4.0 // true
let e: NSString = "Hello" // false
let f: NSString? = "Hello" // true
isOptional(a) // fasle
isOptional(b) // true - warning
isOptional(c) // false
isOptional(d) // true - warning
isOptional(e) // false
isOptional(f) // true - warning
我觉得不错。 swift4
你可以这样做:
extension Mirror {
static func isOptional(any: Any) -> Bool {
guard let style = Mirror(reflecting: any).displayStyle,
style == .optional else { return false }
return true
}
}
用法:
XCTAssertTrue(Mirror.isOptional(any: Optional(1)))
或者如果您需要从 Any 转换为 Optional
protocol _Optional {
var isNil: Bool { get }
}
extension Optional: _Optional {
var isNil: Bool { return self == nil }
}
func isNil (_ input: Any) -> Bool {
return (input as? _Optional)?.isNil ?? false
}
用法:
isNil(nil as String?) // true
isNil("") // false
选项符合 ExpressibleByNilLiteral
,因此您可以使用:
let t = Optional<String>.self
t is ExpressibleByNilLiteral.Type // true
我正在尝试确定给定类型 t
(Any.Type
) 是否为可选类型,我正在使用此测试
t is Optional<Any>.Type
但它 returns 总是错误的。
那么有什么办法可以实现吗?
您可以使用泛型来实现:
func isOptional<T>(x:T?)->Bool
{
return true
}
func isOptional<T>(x:T)->Bool
{
return false
}
编辑
上面的代码可以用来判断一个变量是否是可选类型。 我想出了解变量 包含 类型的唯一方法是使用反射:
var t1:Any.Type=(String?).self
var t2:Any.Type=(String).self
Mirror(reflecting: t1).description
Mirror(reflecting: t2).description
第一次调用 Mirror 给出字符串 "Mirror for Optional<String>.Type"
,第二次调用给出 "Mirror for String.Type"
.
我知道比较字符串不是进行此检查的便捷方法,我会再次尝试找到性能更高的东西..
假设您正在尝试做的是这样的事情:
let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false
遗憾的是 swift 目前(从 Swift 2 开始)不支持 covariance nor contravariance 并且无法直接针对 Optional.Type
进行类型检查:
// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error
另一种方法是 Optional
扩展特定协议,并检查该类型:
protocol OptionalProtocol {}
extension Optional : OptionalProtocol {}
let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true
聚会有点晚了。但是,我运行陷入了同样的问题。这是我的代码。
func isOptional(_ instance: Any) -> Bool {
let mirror = Mirror(reflecting: instance)
let style = mirror.displayStyle
return style == .optional
}
let a: Int = 1 // false
let b: Int? = 2 // true
let c: Double = 3.0 // false
let d: Double? = 4.0 // true
let e: NSString = "Hello" // false
let f: NSString? = "Hello" // true
isOptional(a) // fasle
isOptional(b) // true - warning
isOptional(c) // false
isOptional(d) // true - warning
isOptional(e) // false
isOptional(f) // true - warning
我觉得不错。 swift4
你可以这样做:
extension Mirror {
static func isOptional(any: Any) -> Bool {
guard let style = Mirror(reflecting: any).displayStyle,
style == .optional else { return false }
return true
}
}
用法:
XCTAssertTrue(Mirror.isOptional(any: Optional(1)))
或者如果您需要从 Any 转换为 Optional
protocol _Optional {
var isNil: Bool { get }
}
extension Optional: _Optional {
var isNil: Bool { return self == nil }
}
func isNil (_ input: Any) -> Bool {
return (input as? _Optional)?.isNil ?? false
}
用法:
isNil(nil as String?) // true
isNil("") // false
选项符合 ExpressibleByNilLiteral
,因此您可以使用:
let t = Optional<String>.self
t is ExpressibleByNilLiteral.Type // true