【问题标题】:Swift 1.2 "Cannot express tuple conversion" errorSwift 1.2“无法表达元组转换”错误
【发布时间】:2015-03-04 22:33:01
【问题描述】:

此方法在 Swift 的最新稳定版本中运行良好,但在 Swift 1.2 中无法编译:

  final func rotateBlocks(orientation: Orientation) {
    if let blockRowColumnTranslation:Array<(columnDiff: Int, rowDiff: Int)> = blockRowColumnPositions[orientation] {
        for (idx, (columnDiff:Int, rowDiff:Int)) in enumerate(blockRowColumnTranslation) {
            blocks[idx].column = column + columnDiff
            blocks[idx].row = row + rowDiff
        }
    }
}

这一行:

for (idx, (columnDiff:Int, rowDiff:Int)) in enumerate(blockRowColumnTranslation) {

抛出以下错误:

“无法表示元组转换”(index:Int, element:(columnDiff:Int,rowDiff:Int)) 到“(Int, (Int, Int))”

关于这里发生了什么以及如何解决它的任何想法?

【问题讨论】:

  • 我得到了在 Swift 1.2 中编译的代码,但不得不对 blockRowColumnPositionsOrientation 等未列出类型的确切声明和/或推断类型进行大量猜测. 将其提炼成一个应该 (/did) 编译的完整文件。

标签: ios swift


【解决方案1】:

我会使用typealias 来简化,但以下编译对我来说没有错误。

var row: Int = 0
var column: Int = 1
struct block {
    var column: Int
    var row: Int
}
var blocks = [block]()

enum Orientation { case Up; case Down; }
typealias Diff = (columnDiff: Int, rowDiff: Int)
typealias DiffArray = Array<Diff>
typealias DiffArrayDict = [Orientation: DiffArray]

var blockRowColumnPositions = DiffArrayDict();

func rotateBlocks(orientation: Orientation) {
    if let blockRowColumnTranslation: DiffArray = blockRowColumnPositions[orientation] {
        for (idx, diff) in enumerate(blockRowColumnTranslation) {
            blocks[idx].column = column + diff.columnDiff
            blocks[idx].row = row + diff.rowDiff
        }
    }
}

【讨论】:

    【解决方案2】:

    我遇到了同样的事情,并且能够通过为元组添加 element: 标签来使其正常工作:

    for (idx, element: (columnDiff: Int, rowDiff: Int)) in enumerate(blockRowColumnTranslation) {
        blocks[idx].column = column + element.columnDiff
        blocks[idx].row = row + element.rowDiff
    }
    

    【讨论】:

    • 这是要走的路! (根据swift中的错误)
    • 现在,如果有人能解释为什么需要 element: 标签但最初的 index: 标签不是,那会很有帮助:)
    【解决方案3】:

    对我来说看起来像一个 Swift 错误。更一般地说,这被破坏了:

    let pair = (a: 1, b: 2)
    // normally those named elements don't matter, this is fine:
    let (x,y) = pair
    // but add a bit of nesting:
    let indexed = (index: 1, pair)
    // and, error: 
    let (i, (x,y)) = indexed
    // cannot express tuple conversion '(index: Int, (a: Int, b: Int))' to '(Int, (Int, Int))'
    

    我会尝试从数组的元组声明中删除类型名称(即Array&lt;(Int,Int)&gt; 而不是Array&lt;(columnDiff: Int, rowDiff: Int)&gt;),看看是否有帮助。

    在其他可能相关的新闻中,这似乎导致 1.2 编译器崩溃:

    let a: Array<(Int,Int)> = [(x: 1,y: 2)]
    

    【讨论】:

    • 我也遇到了段错误:-(
    【解决方案4】:

    谢谢各位!我最后只是将它重写为一个 for 循环.. 这并不令人兴奋,但它似乎可以正常工作:

      final func rotateBlocks(orientation: Orientation) {
    
        if let blockRowColumnTranslation:Array<(columnDiff: Int, rowDiff: Int)> = blockRowColumnPositions[orientation] {
    
            for var idx = 0; idx < blockRowColumnTranslation.count; idx++
                {
                let tuple = blockRowColumnTranslation[idx]
                blocks[idx].column = column + tuple.columnDiff
                blocks[idx].row = row + tuple.rowDiff
            }
        }
    }
    

    【讨论】:

    • 如果让你感觉好点,你可以把for改写成for idx in indices(blockRowColumnTranslation) { }
    • 我的怎么了?同样为了一致性,为什么不将blocks 保留为一个元组数组并在一个赋值语句中执行?
    • 就此而言,真正快速的方法是将块(闭包)传递给map
    • @BaseZen,你的实现完全没有问题——我只是一个初学者,我有一个作业到期:)
    【解决方案5】:
    final func rotateBlocks(orientation: Orientation) {
        if let blockRowColumnTranslation = blockRowColumnPositions[orientation] {
            for (idx, diff) in enumerate(blockRowColumnTranslation) {
                blocks[idx].column = column + diff.colunmDiff
                blocks[idx].row = row + diff.rowDiff
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多