我看到的东西对我来说没有意义。这是我的代码......
dropFirst()
&#39;让&#39;即使ArraySlice<SeparatorToken>
返回let remainingSeparatorTokens:[SeparatorToken] = Array(separatorTokens.dropFirst())
,也会导致此编译错误。
如果没有更多的上下文,表达的类型是不明确的
为什么这个含糊不清?我错过了什么?
我也尝试过像这样完全合格,但这也不起作用......
{{1}}
答案 0 :(得分:6)
在通用扩展中,类型参数绑定到它们的范围。我不确定这是不是一件好事(或者可能它真的是一个错误),但它会一直显示,所以这里的类型参数隐含地想要String
。
一个更简单的例子:
let x = Array() // error: generic parameter 'Element' could not be inferred
这是有道理的。但是把它放在一个扩展名中:
extension Array {
func f() {
let x = Array()
}
}
此编译,x
的类型为[Element]
。
在您的情况下,您已将Element
设置为String
,因此致Array.init
的电话想要创建一个[String]
并且它已获得困惑因为SeparatorToken != String
。您需要明确传递type参数(正如您已发现的那样):
let remainingSeparatorTokens = Array<SeparatorToken>(separatorTokens.dropFirst())
同样,我并不认为这是Swift中的一个功能,甚至可能被视为一个错误。但它非常一致。
答案 1 :(得分:1)
我只是在游乐场中运行您的代码并按如下方式更新,然后错误消失了:
import UIKit
import Foundation
enum SeparatorPaddingLocation{
case beforeSeparator
case afterSeparator
}
struct SeparatorToken{
let separator : Character
let formattedSeparator : String
let paddingLocation : SeparatorPaddingLocation
}
extension Array where Element == String {
func aligned(separatorTokens:[SeparatorToken]) -> [String] {
// I update code here
let remainingSeparatorTokens = Array<SeparatorToken>(separatorTokens.dropFirst())
return self
}
}
根据swift,当您使用Array初始化时,Array需要类型。
我希望这对你有用。
有关阵列访问的详细信息:https://developer.apple.com/documentation/swift/array
答案 2 :(得分:1)
这是不一个错误,没有任何神秘或类似错误的事情。
不是错误:这是==
子句中where
运算符可用的原因:要求Element
为String
类型{1}} ,正如here所解释的那样。在页面中搜索“您还可以编写一个通用where子句,需要Item为特定类型”。
不像bug一样:当你进入扩展并调用Array
初始值设定项时,编译器会使用where
子句来指示{{1}的特化}} 你要。您的Array
条款代表where
,所以String
就是Array<String>
。将ArraySlice<SeparatorToken>
传递给Array<String>
初始化程序时,编译器无法读懂您的想法。你犯了错误,或者你真的想要Array<ArraySlice<SeparatorToken>>
吗?因此关于歧义的错误信息。
以下是OP代码的简化和注释版本,以防有人发现它具有启发性。
class Foo<T> {
var theFoo: T!
init() { theFoo = nil }
init(_ aFoo: T) { theFoo = aFoo }
}
extension Foo where T == Int {
func bar() {
// This one fails, because our where clause
// says this extension applies to Foo<Int>,
// but now we're trying to assign it to a Foo<String>
let aFoo: Foo<String> = Foo()
// This one also fails, for the same reason.
// It uses the other initializer, but we're
// still inside the Foo<Int> extension.
let bFoo: Foo<String> = Foo("bFoo")
// This one works, because we're expressly
// overriding the where clause
let cFoo: Foo<String> = Foo<String>("cFoo")
}
}
歧义错误是有道理的。我在where
子句中告诉编译器将其设为Int
扩展名,因此创建了Foo<Int>
s。但后来我尝试将它们分配给Foo<String>
类型的变量。编译器无法判断我是否真的想要Foo<String>
或者我犯了错误,所以它放弃了。