繁体   English   中英

Swift错误消息中的'(String)'和'String'有什么区别

[英]What is the difference between '(String)' and 'String' in a Swift error message

  1. 我编写了一个函数,该函数使用非可选的String作为参数。
  2. 我声明了String类型的变量属性,这也不是可选的。
  3. 当我尝试使用此属性作为参数调用函数时,出现以下错误。

无法使用类型为((String)'的参数列表调用'localesForCountryCode'

请注意,错误将类型列出为'(String)'而不是'String' 括号是什么意思? 以为他们的意思是该类型是可选的,但是在任何地方都没有声明为可选的。

我的功能(NSLocale的扩展):

func localesForCountryCode(countryCode: String) -> [NSLocale] {
    let localeIdentifiers = localeIdentifiersForCountryCode(countryCode)
    var locales = [NSLocale]()
    for localeIdentifier in localeIdentifiers {
        let localeForIdentifier = NSLocale(localeIdentifier: localeIdentifier)
        locales.append(localeForIdentifier)
    }
    return locales
}

调用我的函数的代码

let currentCountryCode = "US"
var localesForCurrentCountry = [NSLocale]()

func updateWithNewLocation(newLocation: CLLocation) {
    geoCoder.reverseGeocodeLocation(newLocation, completionHandler: { (placemarks, error) -> Void in
        if placemarks.count > 0 {
            let placemark = placemarks.first as! CLPlacemark
            self.currentCountry = placemark.country
            self.localesForCurrentCountry = NSLocale.localesForCountryCode(self.currentCountryCode)   
        }
    })
}

更新1

当我将函数代码从NSLocale扩展名移到要从中调用函数的视图控制器时,错误消失了。 有什么想法可能是这种情况吗? 绝对没有对功能进行任何更改。

更新2

我继续遇到这个问题。 以下是另一个示例。 同样,它似乎仅在将函数作为类方法调用时发生。 在此处输入图片说明

我在重新阅读您的问题,并意识到您的问题实际上不是您的问题。 您的问题与括号无关(有关原因,请参见下文)。 您只是在调用错误的方法。 NSDateComponentsFormatter是一个类。 stringFromTimeInterval()是一个实例方法。 您必须创建一个实际的日期格式化程序才能使用。 如果要使用默认值,可以执行以下操作:

return NSDateComponentsFormatter().stringFromTimeInterval(unwrappedTimespan)

注意额外的括号。 不过,您可能不希望使用默认值。 您可能要配置一个。 有关该主题的介绍,请参见日期格式化程序。 请注意,创建日期格式化程序可能会非常昂贵,因此您通常希望重用它们。

您正在使用localesForCountryCode做同样的事情。 这是一个实例方法,而不是类方法。 您必须先创建一个NSLocale

但是,这确实打开了一个有趣的话题。 为什么NSDateComponentsFormatter.stringFromTimeInterval()就像一个函数,您只是将错误的参数传递给它? 为什么不说“嘿,您正在调用类方法?” 这是因为它你只是传递了错误的参数的函数。

每个方法实际上只是一个将目标对象作为第一个参数的咖喱函数。 请参阅Ole Begemann对该主题的快速介绍: 实例方法是Swift中的Curried函数


关于括号的明确问题还有更多内容:

正如其他人指出,一个(String)是一个元组String 重要的一点是,在Swift中,任何类型都可以轻易地转换为该类型的一元组,因此此处多余的括号并不重要。 Swift中的String(String)之间没有有意义的区别。

从技术上讲,所有Swift函数都采用一个值并返回一个值。 因此,人们可以正确地想到:

func f(x: Int, y: Int) -> Int

作为一个接受元组(Int,y:Int)并返回Int (或者可能是(Int)函数;我相信Swift实际上确实是前者)。 这与Swift中的currying工作方式巧妙地联系在一起。 在更简单的情况下:

func f(x: Int)

从技术上讲,这是一个函数(Int)然后返回() 这就是为什么有时您会看到(Type)显示在错误消息中的原因。 但这不是有意义的区别。

String -简单的String类型。 但是(String) -这是一个称为Tuple的复合类型。
这意味着您将向您传递函数Tuple ,而不是String


复合类型是在Swift语言本身中定义的没有名称的类型。 有两种复合类型:函数类型和元组类型。 复合类型可以包含命名类型和其他复合类型。 例如,元组类型(Int,(Int,Int))包含两个元素:第一个是命名类型Int,第二个是另一种复合类型(Int,Int)。

通常,错误消息显示(String)因为这是元组/参数列表。 如果您的方法需要一个String ,然后是一个Int ,则可能会出现一条错误消息(String, paramName: Int)

到目前为止,基本上一切都很好。 您需要向我们展示代码,以便我们能够解决您的确切问题。 因为String(String)在给定的情况下通常应该匹配。

考虑以下示例:

func k (a:String, b:Int) {}
k(12, b:"123")

这将导致错误

无法使用类型为(Int,b:String)的参数列表调用'k'

k("12", b:123)

符合您的期望。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM