【问题标题】:Swift parameter's type not properly inferred?Swift 参数的类型没有正确推断?
【发布时间】:2015-01-10 02:00:06
【问题描述】:

String 有以下初始化器(其中很多):

init(count: Int, repeatedValue: Character)
init(count: Int, repeatedValue: UnicodeScalar)

所以下面的工作不应该吗?

let str = String(count:8, repeatedValue:"*")    // Error: "Extra argument 'count' in call"

编译器不应该能够推断出类型吗?!即使双引号 严格用于字符串文字,CharacterUnicodeScalar 都符合 UnicodeScalarLiteralConvertible 协议。那么这里发生了什么?

当然,我总是可以做到repeatedValue:("*" as Character),但是推断类型有什么意义呢?!

【问题讨论】:

  • 也许正是因为这种模棱两可?由于您的字符串文字可以转换为匹配任一方法,编译器应该选择哪一个?

标签: swift type-inference


【解决方案1】:

这里的问题(正如@Thilo 已经提到的)是协议一致性的模糊性。

Character > ExtendedGraphemeClusterLiteralConvertible > UnicodeScalarLiteralConvertible
UnicodeScalar > UnicodeScalarLiteralConvertible

编译器会检查这些协议,但当它遇到UnicodeScalarLiteralConvertible 时,它不知道该选择哪个初始化程序。

您可以通过使用独特的初始化器扩展 String 来简化此操作:

extension String {
    init(count: Int, repeatedCharacter: Character) {
        self.init(count: count, repeatedValue: repeatedCharacter)
    }
}

let str1 = String(count: 8, repeatedCharacter: "*")
println(str1)

或(虽然我认为有点过头了)一个自定义运算符,它明确表明它是Character

postfix operator • {}
postfix func •(c: Character) -> Character { return c }

let str2 = String(count: 8, repeatedValue: "*"•)
println(str2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2017-04-10
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2014-08-31
    相关资源
    最近更新 更多