如何在Swift中创建一个通用函数,除非它是可选参数,否则它将拒绝给定参数? [英] How to create a generic function in Swift that will reject the given parameter unless it is an Optional?
问题描述
这个问题是我之前的问题的跟进:
您可能想给这个协议起一个更好的名字,但是我不认为它会带来任何问题,除非您自己制作 建议:使用初始化程序. (不利的是,参数标签必须要消除歧义,但由于这种情况的怪异之处,我个人喜欢明确性.例如,Swift可以很容易地强制说某些东西不是 可选的,反之亦然. ) + This question is a follow up to my earlier question: I expected the system to report non protocol conformance, but it does not! Why? Please read the referred question for you to get a better idea of the
constraints at hand. I created a generic function in Swift that will reject its parameter unless such a parameter is Meaning, any calls to Errors like: My only question is: Is there a simpler solution? To make it clear:
You might want to give this protocol a better name, but I don't foresee any problems with it as-is, unless you're making your own Recommendation: use an initializer. (Downside is the argument label being necessary to disambiguate, but I personally like the explicitness because of how weird this case is. i.e. Swift makes it easy to enforce that something is not optional, but not vice versa.) +
这篇关于如何在Swift中创建一个通用函数,除非它是可选参数,否则它将拒绝给定参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!ExpressibleByNilLiteral
无法包装的类型.
protocol ExpressibleByNilLiteral: Swift.ExpressibleByNilLiteral {
associatedtype Wrapped
}
extension Optional: ExpressibleByNilLiteral { }
func onlyCallableByAnOptional<Optional: ExpressibleByNilLiteral>(_ optional: Optional) -> Optional.Wrapped? {
optional as? Optional.Wrapped
}
extension Optional: ExpressibleByNilLiteral {
init<Optional: ExpressibleByNilLiteral>(optional: Optional) where Optional.Wrapped == Wrapped {
self = optional as? Wrapped
}
}
if let v = Optional(optional: i) { // ERROR, as was desired.
print("integer \(v)")
}
if let v = Optional(optional: oi) { // OK, as expected.
print("optional integer \(v)")
}
Optional
. The function I created fully works and does what I desire.onlyCallableByAnOptable(...)
, even inside an if let
, will yield error due to non-protocol conformance, exactly as desired. Argument type 'UIColor' does not conform to expected type 'Optable'
func onlyCallableWithAnOptinalParameter<T>(:T)->T
needs to work when called in an if let
statement like func test()
does.protocol Optable {
associatedtype OptableType
func optionalOptable() -> OptableType?
}
func onlyCallableByAnOptable<T>( _ value: T) -> T.OptableType? where T: Optable {
return value.optionalOptable()
}
extension Optional: Optable {
typealias OptableType = Wrapped //: Wrapped is the type of the element, as defined in Optional
func optionalOptable() -> OptableType? {
return self
}
}
class TestOptable {
static func test()
{
let c = UIColor.blue
let s = "hi"
let i = Int(10)
let oi: Int? = 10
if let v = onlyCallableByAnOptable(c) { // ERROR, as was desired.
print("color \(v)")
}
if let v = onlyCallableByAnOptable(s) { // ERROR, as was desired.
print("string \(v)")
}
if let v = onlyCallableByAnOptable(i) { // ERROR, as was desired.
print("integer \(v)")
}
if let v = onlyCallableByAnOptable(oi) { // OK, as expected.
print("optional integer \(v)")
}
}
}
ExpressibleByNilLiteral
types that don't wrap.protocol ExpressibleByNilLiteral: Swift.ExpressibleByNilLiteral {
associatedtype Wrapped
}
extension Optional: ExpressibleByNilLiteral { }
func onlyCallableByAnOptional<Optional: ExpressibleByNilLiteral>(_ optional: Optional) -> Optional.Wrapped? {
optional as? Optional.Wrapped
}
extension Optional: ExpressibleByNilLiteral {
init<Optional: ExpressibleByNilLiteral>(optional: Optional) where Optional.Wrapped == Wrapped {
self = optional as? Wrapped
}
}
if let v = Optional(optional: i) { // ERROR, as was desired.
print("integer \(v)")
}
if let v = Optional(optional: oi) { // OK, as expected.
print("optional integer \(v)")
}