【问题标题】:Swift 2 IntrospectionSwift 2 内省
【发布时间】:2016-03-13 12:08:57
【问题描述】:

我正在将一些“旧”的 Swift 代码转换为 Swift 2.0,但遇到了一个我无法摆脱的错误。
我的函数接收一个类型的数组(随便),并返回一个相同类型的新数组。

此代码不再适用于 Swift 2.0:

func makePattern1<T>(var list: Array<T>) -> Array<T> {
    let theType = list.dynamicType
    var result = theType()
    for i in 1..<list.count {
        result.append(list[i])
        result.append(list[i-1])
    }
    return result
}

给出错误消息:“从元类型值初始化必须明确引用'init'”。

更正代码: var result = theType.init() 给出“没有更多上下文的表达式类型不明确”错误。

我错过了什么?

【问题讨论】:

  • 您有这样做的理由吗?看起来你想要的可以通过map 更轻松地完成。
  • 另外,是什么阻止你说var result = Array&lt;T&gt;()
  • var result = Array&lt;T&gt;() 工作正常,谢谢。
  • 你能举一个map的例子吗?

标签: swift generics swift2 introspection


【解决方案1】:

只是为了好玩:另一种解决方案:

func makePattern2<T>(list: [T]) -> [T] {
     return zip(list.dropFirst(), list).flatMap { [$0, $1] }
}

let m = makePattern2([1,2,3,4,5])
print(m) // [2, 1, 3, 2, 4, 3, 5, 4]

备注:

  • list.dropFirst() 是除第一个数组元素之外的所有元素的序列。
  • zip(list.dropFirst(), list) 然后是一个序列 (list[$0.i+1], list[$0.i]) 元组。
  • flatMap { [$0, $1] } 再次将这些元组组合成一个数组。

【讨论】:

  • 非常好。这个flatMap 的闭包只使用闭包本身的参数。这是一个纯函数式的解决方案。
【解决方案2】:

此代码是用 Swift 2.1 编写的,并且确实使用了您在 cmets 中请求的 map 函数。

func makePattern1<T>(list: [T]) -> [T] {
    return list[0..<list.count-1]
        .enumerate()
        .map { [list[$0.index+1], list[$0.index]] }
        .flatten()
        .map { $0 as T }
}

更新 #1

(感谢 Martin R)

func makePattern1<T>(list: [T]) -> [T] {
    return list[0..<list.count-1]
        .enumerate()
        .flatMap { [list[$0.index+1], list[$0.index]] }
}

更新 #2

func makePattern1<T>(list: [T]) -> [T] {
    return [Int](1..<list.count).flatMap { [list[$0], list[$0-1]] }
}

测试

makePattern1([1,2,3,4,5]) // > [2, 1, 3, 2, 4, 3, 5, 4]

【讨论】:

  • .map + flatten可以组合成flatMap,然后也可以去掉最后的“人工”.map { $0 as T }
猜你喜欢
  • 2014-07-25
  • 2016-07-19
  • 1970-01-01
  • 2018-09-21
  • 2016-05-19
  • 2018-11-03
  • 1970-01-01
  • 2017-10-18
  • 2014-01-06
相关资源
最近更新 更多