【问题标题】:Same-type constraint 'Element' == 'Array<Element>' is recursive相同类型的约束 'Element' == 'Array<Element>' 是递归的
【发布时间】:2020-05-14 02:50:36
【问题描述】:

我想为矩阵制作一个漂亮的初始化程序,让我可以使用默认元素定义行数和列数。如何为数组创建扩展?当我尝试以下方式时,

extension Array where Element == Array<SubElement> {

    init(rows: Int, columns: Int, emptyDefault: SubElement) {

        self = [] 
        // implementation
    }

}

我收到以下错误:

// Same-type constraint 'Element' == 'Array<Element>' is recursive

一个示例用法是

self = [[UIColor]](rows: 20, columns: 30, emptyDefault: .blue)
// This would create a matrix with 20 rows, each row having an array of 30 .blue

我希望能够做这样的事情。

【问题讨论】:

    标签: arrays swift extension-methods


    【解决方案1】:

    Leo 的回答很好。 ?

    但更严格的解决方案看起来像这样,将约束移动到初始化器:

    extension Array {
      init<Element>(rows: Int, columns: Int, emptyDefault: Element) where Self.Element == [Element] {
    
      }
    }
    

    【讨论】:

    • 哦,聪明。我喜欢它。
    • 我也喜欢它,直到你把那行写得太长了! where 子句通常会使行太宽,因此我将 where 与以任何限制开头的关键字对齐。另外,我故意省略了右括号。像这样,它不会编译!
    • 对不起!我刚看到这个。你改回来了吗?
    【解决方案2】:

    如果您需要创建一个元素矩阵,您可以扩展RangeReplaceableCollection 并将其元素限制为RangeReplaceableCollection。您需要将 Element.Element 类型的默认元素添加到您的初始化程序以填充您的集合:

    extension RangeReplaceableCollection where Element: RangeReplaceableCollection { 
        init(rows: Int, columns: Int, element: Element.Element) { 
            self.init(repeating: .init(repeating: element, count: columns), count: rows) 
        }
    }
    

    用法:

    let matrix: [[UIColor]] = .init(rows: 3, columns: 3, element: .blue)
    

    【讨论】:

    • 您能否在答案中也包含那个空的init() 实现?看到那个被删除我很难过。
    • 您可以只将 init 作为元素传递。您需要使类型符合协议的另一种方法
    • 正如我所说,您只需将 init 作为元素传递 let matrix: [[String]] = .init(rows: 3, columns: 3, element: .init())
    • protocol HasInit { init() } extension String: HasInit {} extension RangeReplaceableCollection where Element: RangeReplaceableCollection, Element.Element: HasInit { init(rows: Int, columns: Int) { self.init(repeating: .init(repeating: Element.Element(), count: columns), count: rows) } }
    • IMO 通过init() 是首选。
    【解决方案3】:

    它并不完美,这是我的临时工作:

    extension Collection where Element: Collection {
    
    }
    

    【讨论】:

    • 好电话。奇怪的是 Swift 允许递归一致性但不允许递归相等。
    • @LeoDabus,已更新。我想向通用数组数组添加方法,它可以在每个单元格中获取一个通用元素。
    • 很简单,我只想用空单元格初始化一个矩阵,同时定义行数和列数。我可以补充一下。。我不知道如何使它更具体。
    • [ [/*row1*/ "cell 1", "cell 2" ], [/*row2*/ "cell 3", "cell 4" ], [/*row3*/ "单元格 5", "单元格 6" ] ]
    • 哇。非常聪明。谢谢你。如果您想将其发布为答案,那正是我正在寻找的。​​span>
    猜你喜欢
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多