Swift 代码在 playground 中有效,但在命令行工具中无效

Swift code works in playground but not in command line tool

我是 swift 的新手,我正在尝试编写一个简单的正则表达式应用程序,它接受用户输入的文件路径并对文本文件应用多个正则表达式替换。

import Foundation

let shotFilePath = readLine()
// Use contentsOfFile overload.
// ... Specify utf8 encoding.
// ... Ignore errors.
let babySteps = try NSString(contentsOfFile: shotFilePath!,
    encoding: String.Encoding.utf8.rawValue)

let firetruck = #"Ay Ay Sir!"#
var firetruckYou = babySteps.replacingOccurrences(of: firetruck, with: "", options: .regularExpression)

问题出在最后一行代码上。使用硬编码字符串一切正常,但是当我允许用户输入它时,出现以下错误:

如果我将 babySteps 字符串硬编码为常量,没问题,但如果我从文件中导入它,事情就会变糟。

是什么导致 Swift 在这两个实例中表现不同?非常感谢!

您必须将范围传递给 NSString 方法。例如:

let range = babySteps.range(of: String(babySteps))

为什么?

因为您正在使用 NSString。在 Swift 中,我们更喜欢使用 String。它们是不同的。看看这两个:

babyStepsString.replacingOccurrences(of: firetruck,
                                     with: "",
                                     options: .regularExpression,
                                     range: <#Range<String.Index>?#>)

babyStepsNSString.replacingOccurrences(of: firetruck,
                                       with: "",
                                       options: .regularExpression,
                                       range: <#NSRange#>)

如您所见,这两种方法几乎相同,但 String 方法采用 optional 并且您可以传递 nil 或干脆不传递任何东西给它具有默认 nil 值。 但是NSString版本需要你传递一个范围。


升级

您可以实施扩展以使其更像您想要的:

extension NSString {
    open func replacingOccurrences(of target: String, with replacement: String, options: NSString.CompareOptions = []) -> String {
        replacingOccurrences(of: target, with: replacement, options: options, range: self.range(of: String(self)))
    }
}

现在您的原始代码应该可以工作了。

我不知道为什么最初发布这个的人删除了他的答案,但这是他非常优雅的解决方案:

let babySteps = try String(contentsOfFile: shotFilePath!, encoding: .utf8)

感谢 Mojtaba 后来也指出了 String 和 NSString 的区别!