'Array<Element>' 不可转换为 'Array<Int>'

'Array<Element>' is not convertible to 'Array<Int>'

我可以创建一个迭代器来创建前缀:

extension Array where Element == Int {
  func prefixesInt() -> AnyIterator<[Element]> {
    var length = 0
    return AnyIterator {
      guard length < self.count else { return nil }
      length += 1
      return Array(self.prefix(length))
    }
  }
}

for prefix in [1,10,5].prefixesInt() {
  print(prefix)  // Prints: [1]  then  [1, 10]  then [1, 10, 5]
}

现在我想通过以下方式实现与其他类型相同的效果:

1) 将类型编码为 Ints

2) 使用相同的前缀函数

3)解码回原始类型

[我知道可能有其他方法可以实现这一点,但出于各种原因我想遵循这一行,也想了解更多。]

所以我需要:

extension Array where Element: Equatable {
  func encode() -> [Int] {
    return map { self.firstIndex(of: [=15=])! }
  }
}
print(["A", "B", "A", "C"].encode())  // Prints: [0, 1, 0, 3]

extension Array where Element == Int {
  func decode<Output>(_ original: [Output]) -> [Output] {
    return map { original[[=15=]] }
  }
}
print([2,3,0].decode(["P", "Q", "R", "S"]))  // Prints: ["R", "S", "P"]

我现在可以做我想做的事了:

extension Array where Element: Equatable {
  func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return encode().prefixesInt().lazy.map { [=16=].decode(self) }
  }
}

for prefix in ["H","A","T"].prefixes() {
  print(prefix)
}

我现在想更进一步,将转换(在本例中为前缀)转换为参数,我的尝试是:

extension Array where Element: Equatable {
  func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return transform(encode()).lazy.map { [=17=].decode(self) }
  }
}

编译正常,但当我尝试时:

extension Array where Element: Equatable {
  func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
    return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
  }
}

for prefix in ["A","B","C"].prefixes2() {
  print(prefix)
}

然后我得到指示的错误

我卡住了。任何帮助表示赞赏。

完整代码:

print("========== prefixesInt")
extension Array where Element == Int {
  func prefixesInt() -> AnyIterator<[Element]> {
    var length = 0
    return AnyIterator {
      guard length < self.count else { return nil }
      length += 1
      return Array(self.prefix(length))
    }
  }
}

for prefix in [1,10,5].prefixesInt() {
  print(prefix)  // Prints: [1]  then  [1, 10]  then [1, 10, 5]
}

print("============ encode")
extension Array where Element: Equatable {
  func encode() -> [Int] {
    return map { self.firstIndex(of: [=19=])! }
  }
}
print(["A", "B", "A", "C"].encode())  // Prints: [0, 1, 0, 3]

print("============ decode")
extension Array where Element == Int {
  func decode<Output>(_ original: [Output]) -> [Output] {
    return map { original[[=19=]] }
  }
}
print([2,3,0].decode(["P", "Q", "R", "S"]))  // Prints: ["R", "S", "P"]

print("============ prefixes")
extension Array where Element: Equatable {
  func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return encode().prefixesInt().lazy.map { [=19=].decode(self) }
  }
}

for prefix in ["H","A","T"].prefixes() {
  print(prefix)
}

extension Array where Element: Equatable {
  func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return transform(encode()).lazy.map { [=19=].decode(self) }
  }
}

print("============ prefixes2")
extension Array where Element: Equatable {
  func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
    return encodeTransformDecode(transform: prefixesInt)
  }
}

for prefix in ["A","B","C"].prefixes2() {
  print(prefix)
}

在@Carpsen90 和@CRD(感谢两位!)的帮助下,以及一些人阅读了这本优秀的书 "obj Functional Swift"(没有个人联系),我找到了一个解决方案。

实例方法的类型不同于静态方法,如下所示:

extension Int {
  static func doubleStatic(_ x: Int) -> Int { return x * 2 }
  func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) )    // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) )  // Prints: (Int) -> () -> Int

题中prefixesInt的类型实际上是:(Array<Int>) -> () -> AnyIterator<[Int]>.
考虑到这一点,我们可以重写 encodeTransformDecode 如下:

extension Array where Element: Equatable {
  func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return transform(encode())().lazy.map { [=11=].decode(self) }
  }
}

其次,当我们在 prefixes2 中使用它时,我们需要告诉编译器更多关于 prefixesInt 类型的信息,所以:

extension Array where Element: Equatable {
  func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return encodeTransformDecode(transform: Array<Int>.prefixesInt)
  }
}

现在根据需要:

for prefix in ["A","B","C"].prefixes2() {
  print(prefix)
}

给我们:

["A"]
["A", "B"]
["A", "B", "C"]

现在我们可以非常简单地扩展其他功能:

extension Array where Element == Int {
  func suffixesInt() -> AnyIterator<[Element]> {
    var length = 0
    return AnyIterator {
      guard length < self.count else { return nil }
      length += 1
      return Array(self.suffix(length))
    }
  }
}

extension Array where Element: Equatable {
  func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
    return encodeTransformDecode(transform: Array<Int>.suffixesInt)
  }
}

for suffix in ["A","B","C"].suffixes2() {
  print(suffix)
}

正如我的评论中所指出的,您已经在自己的回答中进行了探索,代码中的核心问题是 prefixesInt 的类型不正确。实例方法具有以下形式的类型:

(<object type>) -> (<argument types>) -> <return type>

传递给 <object type> 的值是函数中绑定到 self 的值。所以类型 prefixesInt 是:

([Int]) -> () -> AnyIterator<[Int]>

要修复您的代码,您只需更改 prefixes2:

func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
   return encodeTransformDecode(transform: { [=12=].prefixesInt() } )
}

类型已更改为包含 AnyIterator<[Int]> 而不是 AnyIterator<[Element]> 并且传递闭包 { [=24=].prefixesInt() } 而不仅仅是 prefixesInt (前者将数组作为参数,而编译器传递后者,它是 self.prefixesInt 的 shorthand,作为一个闭包,当前值为 self 预绑定——selfArray<Equatable> prefixes2 被调用)。

HTH


要查看与您生成的代码的联系,请考虑:

<value>.method(<args>)

只是一个 shorthand 用于:

<type of value>.method(<value>)(<args>)

在这种情况下意味着:

[=15=].prefixesInt()

是 shorthand 用于:

Array<Int>.prefixesInt([=16=])()

这是你生产的,但分布在 prefixes() (Array<Int>.prefixesInt) 和 encodeTransformDecode (transform(encode())()) 之间。通过使用 shorthand 并传递闭包,不需要对 encodeTransformDecode 进行任何更改。