Swift: 貌似不允许比较一个String?用一个字符串?
Swift: seemingly not allowed to compare a String? with a String?
我要求用户输入(这有效)并尝试输出不同的结果,具体取决于输入是 nil
、空字符串还是使用 switch
的非空字符串子句(不起作用)。
第一次尝试出错,因为我正在尝试比较可选字符串和非可选字符串:
import Foundation
print("Hi, please enter a text:")
let userInput = readLine(stripNewline: true)
switch userInput {
case nil, "": // Error: (!) Expression pattern of type ‘String’ cannot match values of type ‘String?’
print("You didn’t enter anything.")
default:
print("You entered: \(userInput)")
}
很公平,所以我创建了一个可选的空字符串来比较:
import Foundation
print("Hi, please enter a text:")
let userInput = readLine(stripNewline: true)
let emptyString: String? = "" // The new optional String
switch userInput {
case nil, emptyString: // Error: (!) Expression pattern of type ‘String?’ cannot match values of type ‘String?’
print("You didn’t enter anything.")
default:
print("You entered: \(userInput)")
}
所以这给了我一个错误,说我无法将“字符串?”与“字符串?”进行比较。
这是为什么?他们不知何故仍然不是同一类型?
PS。我觉得我在这里遗漏了一些基本的东西,比如 Troy pointed out about optionals not being "the same type as the corresponding non-otpional type but with the additional possibility of not having a value" (not an exact quote, see his UPDATE at the end of the question: What does an exclamation mark mean in the Swift language?)。但我一直在连接最后的点,为什么这不行。
替换
case `nil`, "":
和
case nil, .Some(""):
请注意,optional 是一个具有两个可能值的枚举:.None
和 .Some(value)
。
关于您使用 String?
的第二个示例,请注意 case
中的匹配是使用 ~=
运算符执行的,该运算符未为可选值定义。
如果定义:
@warn_unused_result
public func ~=<T: Equatable>(lhs: T?, rhs: T?) -> Bool {
return lhs == rhs
}
您的两个示例都将开始工作(不推荐)。
您是否尝试将 userInput 文本作为字符串获取:
let response = userInput ?? ""
switch response {
case "":
print("You didn’t enter anything.")
default:
print("You entered: \(response)")
}
那你就确定是同类型String了
希望有用
只是对现有好的答案的补充:而不是测试
针对 nil
和空字符串你可以反过来
并针对非零字符串进行测试(使用 input?
模式)和
添加 where
约束:
switch userInput {
case let input? where !input.isEmpty:
print("You entered", input)
default:
print("You did not enter anything")
}
等价于:
if case let input? = userInput where !input.isEmpty {
print("You entered", input)
} else {
print("You did not enter anything")
}
但是: readLine()
returns nil
仅在文件结尾处
条件,这意味着不能再从标准中读取数据
输入。因此,终止
在这种情况下的程序:
guard let userInput = readLine(stripNewline: true) else {
fatalError("Unexpected end-of-file")
}
// `userInput` is a (non-optional) String now
if userInput.isEmpty {
print("You did not enter anything")
} else {
print("You entered", userInput)
}
查看不言自明的示例...
let txtArr: [String?] = [nil, "", "some text"]
for txt in txtArr {
switch txt {
case nil:
print("txt is nil")
case let .Some(t) where t.isEmpty:
print("txt is empty string")
default:
print("txt is \(txt)")
}
}
代码打印
txt is nil
txt is empty string
txt is Optional("some text")
我要求用户输入(这有效)并尝试输出不同的结果,具体取决于输入是 nil
、空字符串还是使用 switch
的非空字符串子句(不起作用)。
第一次尝试出错,因为我正在尝试比较可选字符串和非可选字符串:
import Foundation
print("Hi, please enter a text:")
let userInput = readLine(stripNewline: true)
switch userInput {
case nil, "": // Error: (!) Expression pattern of type ‘String’ cannot match values of type ‘String?’
print("You didn’t enter anything.")
default:
print("You entered: \(userInput)")
}
很公平,所以我创建了一个可选的空字符串来比较:
import Foundation
print("Hi, please enter a text:")
let userInput = readLine(stripNewline: true)
let emptyString: String? = "" // The new optional String
switch userInput {
case nil, emptyString: // Error: (!) Expression pattern of type ‘String?’ cannot match values of type ‘String?’
print("You didn’t enter anything.")
default:
print("You entered: \(userInput)")
}
所以这给了我一个错误,说我无法将“字符串?”与“字符串?”进行比较。
这是为什么?他们不知何故仍然不是同一类型?
PS。我觉得我在这里遗漏了一些基本的东西,比如 Troy pointed out about optionals not being "the same type as the corresponding non-otpional type but with the additional possibility of not having a value" (not an exact quote, see his UPDATE at the end of the question: What does an exclamation mark mean in the Swift language?)。但我一直在连接最后的点,为什么这不行。
替换
case `nil`, "":
和
case nil, .Some(""):
请注意,optional 是一个具有两个可能值的枚举:.None
和 .Some(value)
。
关于您使用 String?
的第二个示例,请注意 case
中的匹配是使用 ~=
运算符执行的,该运算符未为可选值定义。
如果定义:
@warn_unused_result
public func ~=<T: Equatable>(lhs: T?, rhs: T?) -> Bool {
return lhs == rhs
}
您的两个示例都将开始工作(不推荐)。
您是否尝试将 userInput 文本作为字符串获取:
let response = userInput ?? ""
switch response {
case "":
print("You didn’t enter anything.")
default:
print("You entered: \(response)")
}
那你就确定是同类型String了
希望有用
只是对现有好的答案的补充:而不是测试
针对 nil
和空字符串你可以反过来
并针对非零字符串进行测试(使用 input?
模式)和
添加 where
约束:
switch userInput {
case let input? where !input.isEmpty:
print("You entered", input)
default:
print("You did not enter anything")
}
等价于:
if case let input? = userInput where !input.isEmpty {
print("You entered", input)
} else {
print("You did not enter anything")
}
但是: readLine()
returns nil
仅在文件结尾处
条件,这意味着不能再从标准中读取数据
输入。因此,终止
在这种情况下的程序:
guard let userInput = readLine(stripNewline: true) else {
fatalError("Unexpected end-of-file")
}
// `userInput` is a (non-optional) String now
if userInput.isEmpty {
print("You did not enter anything")
} else {
print("You entered", userInput)
}
查看不言自明的示例...
let txtArr: [String?] = [nil, "", "some text"]
for txt in txtArr {
switch txt {
case nil:
print("txt is nil")
case let .Some(t) where t.isEmpty:
print("txt is empty string")
default:
print("txt is \(txt)")
}
}
代码打印
txt is nil
txt is empty string
txt is Optional("some text")