您可以这样创建一个字符串扩展名:
extension String {
func someFunc -> Bool { ... }
}
但是,如果您希望它应用于可选字符串怎么办?
var optionalString :String? = ""
optionalString!.someFunc() /* String? does not have a member someFunc */
您可以这样创建一个字符串扩展名:
extension String {
func someFunc -> Bool { ... }
}
但是,如果您希望它应用于可选字符串怎么办?
var optionalString :String? = ""
optionalString!.someFunc() /* String? does not have a member someFunc */
optionalString!.someFunc()
Answers:
在Swift 3.1中,您还可以向可选值添加扩展:
extension Optional where Wrapped == String {
var isBlank: Bool {
return self?.isBlank ?? true
}
}
if myOptionalString?.isBlank {
给可选类型布尔值?还没有展开。
Type Wrapped constrained to non-protocol type String
错误。 这是有关Reddit的一个可能相关的讨论,看来将来可能会解决此问题。
where Wrapped == T
吗?
myOptionalString.isBlank
。没有,?
因为您是在可选本身而不是在上调用它String
。
您可以这样做:
protocol OptionalType { typealias A; var opt: A? { get } }
extension Optional: OptionalType { var opt: A? { return self } }
protocol StringType { var get: String { get } }
extension String: StringType { var get: String { return self } }
extension Optional where Wrapped: StringType {
func getOrElse(s: String) -> String {
return self.opt?.get ?? s
}
}
和:
let optStr: String? = nil
optStr.getOrElse("hello world")
之所以无法约束,Optional
或String
因为那是因为struct
。通过为每个协议创建伪协议,现在我们可以根据需要进行约束。
我觉得迅速放弃了很多东西,只是为了让初学者更容易学习,或者这门语言还不够成熟。
Optional
返回一个String
从Swift 3开始,您不能直接将扩展方法限制为optional String
。正如Daniel Shin的答案所解释的,您可以通过协议获得等效的结果。
但是,您可以在任何类型的Optional上创建扩展方法,并且我发现了一些具有String
返回值的有用方法。这些扩展有助于将值记录到控制台。String
当我想用空字符串替换可能的nil时,已在可选对象上使用了asStringOrEmpty()。
extension Optional {
func asStringOrEmpty() -> String {
switch self {
case .some(let value):
return String(describing: value)
case _:
return ""
}
}
func asStringOrNilText() -> String {
switch self {
case .some(let value):
return String(describing: value)
case _:
return "(nil)"
}
}
}
使用示例:
var booleanValue: Bool?
var stringValue: String?
var intValue: Int?
print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")
booleanValue = true
stringValue = "text!"
intValue = 41
print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")
控制台输出:
booleanValue: (nil)
stringValue: (nil)
intValue: (nil)
booleanValue: true
stringValue: text!
intValue: 41
Optional
与nil指针不同这些扩展说明anOptional
与nil指针不同。anOptional
是enum
指定类型(Wrapped
)的a,表示它包含或不包含值。您可以在Optional
“容器”即使其中可能不包含值。
摘自Swift可选声明
enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
...
}
在代码中,通常使用nil
文字而不是显式.none
枚举的情况来编写不存在值的情况。
更新:有关适用于Swift 2及更高版本的解决方法,请参见Daniel Shin的答案
可选字符串本身不是类型,因此您不能在可选类型上创建扩展名。在Swift中,anOptional
只是一个枚举(加上一些语法糖),可以为None
,也Some
可以包装一个值。要使用String方法,您需要打开optionalString
。您可以轻松地使用可选链接来实现此目的:
optionalString?.someFunc()
如果optionalString
不是nil
,someFunc
将对其进行调用。另一种(不太简洁)的方法是optionalString
在尝试调用该方法之前,使用可选绑定来确定是否具有值:
if let string = optionalString {
string.someFunc() // `string` is now of type `String` (not `String?`)
}
在下面的注释示例中,您无需嵌套多个if
语句,可以检查可选字符串是否在单个字符串中为空字符串if
:
if optionalString?.isEmpty == true {
doSomething()
}
这工作,因为表达式optionalString?.isEmpty
返回一个可选的布尔(即true
,false
或nil
)。所以doSomething()
才会被调用,如果optionalString
是没有 nil
,和如果该字符串是空的。
另一种选择是:
if let string = optionalString where string.isEmpty {
doSomethingWithEmptyString(string)
}
if let str=optString { if str.isEmpty { doSomething(); } }
我希望这是isBlank
可选字符串的扩展
if optStr.isBlank { … }
繁荣。对于像Swift这样的新事物,您会认为最终目标是可读性,因为可读性是可维护的。
发现一些技巧迅速3
class A{
var name:String!;
init(_ name:String?){
self.name = name;
}
}
extension Optional where Wrapped == String {
func compareText(_ other:String?)->Bool{
switch (self,other){
case let(a?,b?):
return a < b;
case (nil,_):
return true;
default:
return false;
}
}
}
let words:[A] = [A("a"),A(nil),A("b"),A("c"),A(nil)];
// let sorted = words.sorted{ 0.name.compareText($1.name) }
// trick
let sorted = words.sorted{ ($0.name as String?).compareText($1.name) }
print(sorted.map{$0.name});
您可以创建一个可选的字符串扩展名。我执行以下操作将可选字符串设置为null,如果它为nil:
extension Optional where Wrapped == String {
mutating func setToEmptyIfNil() {
guard self != nil else {
self = ""
return
}
}
}