首页 文章

Swift:貌似不允许比较String?用字符串?

提问于
浏览
1

我要求用户输入(这可行)并尝试输出不同的结果,具体取决于输入是 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)")
}

所以这给了我一个错误,说我无法将'String?'与'String?'进行比较 .

这是为什么?他们在某种程度上仍然不是同一类型?

PS . 我觉得我在这里缺少一些基本的东西,例如Troy指出的选项不是"the same type as the corresponding non-otpional type but with the additional possibility of not having a value"(不是确切的引用,请参阅问题末尾的更新:What does an exclamation mark mean in the Swift language?) . 但是我确定了.2393586_好的 .

4 回答

  • 1

    更换

    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
    }
    

    你的例子都会开始工作(不推荐) .

  • 0

    您是否尝试将userInput文本作为字符串获取:

    let response = userInput ?? ""
    switch response {
        case "": 
            print("You didn’t enter anything.")
        default:
            print("You entered: \(response)")
    }
    

    然后你会确定它是相同类型的String .

    我希望它有效

  • 3

    作为对现有好答案的补充:不是测试 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() 仅在文件结束条件下返回 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)
    }
    
  • 5

    看到不言自明的例子......

    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")
    

相关问题