相同类型的约束 '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>' 是递归的的主要内容,如果未能解决你的问题,请参考以下文章