【问题标题】:Swift code works in playground but not in command line toolSwift 代码在 Playground 中有效,但在命令行工具中无效
【发布时间】:2020-05-16 17:02:08
【问题描述】:

我对 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 在这两种情况下表现不同?非常感谢!

【问题讨论】:

    标签: swift swift-playground command-line-tool


    【解决方案1】:

    您必须将范围传递给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)))
        }
    }
    

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

    【讨论】:

    • 感谢详细的解释!现在我想我会去了解范围是什么。所以如果我理解你正确使用 String 使范围是可选的,因为 NSString 不能接受 nil 值?
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-14
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 2021-11-01
      • 2017-08-17
      • 2021-11-13
      相关资源
      最近更新 更多