【问题标题】:What is the difference between '(String)' and 'String' in a Swift error messageSwift 错误消息中的 '(String)' 和 'String' 有什么区别
【发布时间】:2015-09-04 18:06:07
【问题描述】:
  1. 我编写了一个将非可选字符串作为参数的函数。
  2. 我声明了一个 String 类型的变量属性,它也不是可选的。
  3. 当我尝试将此属性作为参数调用我的函数时,出现以下错误。

无法使用“(字符串)”类型的参数列表调用“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

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

【问题讨论】:

  • 你能显示使用代码吗?
  • 括号只是表示方法的类型和参数列表。
  • rintaro 这是一个不同的问题。
  • 我想你可能不得不把funcclass func 联系起来,因为你通过NSLocale. 引用它!

标签: ios xcode swift compiler-errors


【解决方案1】:

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

return NSDateComponentsFormatter().stringFromTimeInterval(unwrappedTimespan)

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

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

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

每个方法实际上只是一个将目标对象作为第一个参数的柯里化函数。请参阅 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 中的柯里化工作方式有着微妙的联系。在更简单的情况下:

func f(x: Int)

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

【讨论】:

    【解决方案2】:

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


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

    【讨论】:

    • 但文档还指出:如果括号内只有一个元素,则类型就是该元素的类型。比如(Int)的类型是Int,而不是(Int)
    • @MartinR,是的,现在我明白了。但是我在任何有问题的示例代码之前发布了答案;)无论如何,谢谢您的评论。
    【解决方案3】:

    一般来说,错误消息是(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)
    

    做你所期望的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-26
      • 2016-11-09
      • 2012-08-11
      • 2018-06-07
      • 2012-10-06
      • 2015-12-26
      • 2021-12-21
      • 2012-05-21
      相关资源
      最近更新 更多