'(字符串)'之间有什么区别?和' String'在Swift错误消息中

时间:2015-09-04 18:06:07

标签: ios xcode swift compiler-errors

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

    无法调用' localesForCountryCode'使用类型'(字符串)'

    的参数列表

    请注意,错误会将类型列为'(String)'而不是'String' parens表示什么?想到他们意味着该类型是可选的,但没有任何地方被声明为可选的。

    我的功能(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

    我继续遇到这个问题。以下是另一个例子。同样,它似乎只在函数作为类方法调用时才会发生。 enter image description here

3 个答案:

答案 0 :(得分:3)

我正在重读你的问题,并意识到你的问题不是你的问题。您的问题与括号无关(请参阅下文有关原因)。你只是在调用错误的方法。 NSDateComponentsFormatter是一个班级。 stringFromTimeInterval()是一种实例方法。你必须创建一个实际的日期格式化程序来使用。如果你想要一个默认的,你可以这样做:

return NSDateComponentsFormatter().stringFromTimeInterval(unwrappedTimespan)

请注意额外的括号。不过,你可能不想要默认的。您可能想要配置一个。有关该主题的介绍,请参阅Date Formatters。请注意,日期格式化程序的创建成本非常高,因此您通常希望重用它们。

你对localesForCountryCode做了同样的事情。这是一个实例方法,而不是类方法。您必须先创建NSLocale

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

每个方法实际上只是一个以目标对象作为第一个参数的curried函数。请参阅Ole Begemann对该主题的快速介绍:Instance Methods are Curried Functions in Swift

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

正如其他人所说,(String)String的一元组。重要的一点是,在Swift中,任何类型都可以简单地转换为该类型的一元组,因此这里的额外括号并不重要。 Swift中String(String)之间没有任何有意义的区别。

所有Swift函数在技术上都取一个值并返回一个值。所以人们可以正确地想到:

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

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

func f(x: Int)

这是一个技术上需要(Int)并返回()的函数。这就是为什么有时您会看到(Type)出现在错误消息中的原因。但这不是一个有意义的区别。

答案 1 :(得分:0)

String - 简单的String类型。 但是(String) - 它是一种名为Tuple的复合类型 这意味着你传递给你的是Tuple,而不是String

  

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

答案 2 :(得分:0)

通常,错误消息显示为(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)

做你期望的事。