相同类型的约束 'Element' == 'Array<Element>' 是递归的

Posted

技术标签:

【中文标题】相同类型的约束 \'Element\' == \'Array<Element>\' 是递归的【英文标题】: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

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

【问题讨论】:

【参考方案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>

以上是关于相同类型的约束 'Element' == 'Array<Element>' 是递归的的主要内容,如果未能解决你的问题,请参考以下文章

556. Next Greater Element III

打字稿:为啥类型别名满足约束但相同的接口不满足?

数组的方法之(Array.prototype.forEach() 方法)

xml的schema约束(Java)

Element类型知识大全

js需要一个查找一个数组中相同的元素算法。