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

Posted

技术标签:

【中文标题】Swift 代码在 Playground 中有效,但在命令行工具中无效【英文标题】:Swift code works in playground but not in command line tool 【发布时间】: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 在这两种情况下表现不同?非常感谢!

【问题讨论】:

【参考方案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 之间的区别!

【讨论】:

以上是关于Swift 代码在 Playground 中有效,但在命令行工具中无效的主要内容,如果未能解决你的问题,请参考以下文章

斯威夫特 2.1,xcode 7.2。简单的新手关于为啥它在 Playground 中有效但在应用程序中无效

是否可以在 iPad Swift Playground 中使用 Metal 着色器代码?

如何检查 Playground 的 swift 版本?

swift 在控制台中打印所有可用字体。尝试在Xcode Playground中粘贴此代码。

在 Swift/Playground 中使用 .append 选项到数组结束时出现错误

在 UIViewController 类中使用“视图”时,Swift Playground 崩溃