Swift 数组与 c 数组有何不同
Posted
技术标签:
【中文标题】Swift 数组与 c 数组有何不同【英文标题】:How are Swift arrays different than c arrays 【发布时间】:2016-02-12 19:39:52 【问题描述】:我正在努力将我的一些使用原始 c 数组的 ObjC 代码转换为 Swift 数组。但是,在使用游乐场时,我发现了一些奇怪的行为。
例如,以下在 Swift 中是完全有效的
var largearray : [[Float]] = []
largearray.append([0,1,2]) //3 elements
largearray.append([3,4,5]) //3 elements
largearray.append([6,7,8,9]) //-4- elements
largearray.append([10,11,12]) //3 elements
//pull those back out
largearray[1][0] //gives 3
largearray[1][2] //gives 5
//largearray[1][3] //error
largearray[2][0] //gives 6
largearray[2][2] //gives 8
largearray[2][3] //gives 9
largearray[3][0] //gives 10
我不明白 Swift 怎么可能有混合的行长。有人可以解释这里发生了什么,因为文档没有详细说明。我很好奇它是否在幕后存储了一个连续的浮点数组。
然后我的另一个问题是关于访问行或列。在 Swift 中,我看到我可以使用 largearray[0]
访问整行,给出 [0,1,2],就像 largearray[2]
给出 [6,7,8,9]。这不是 c 数组的索引方式。 (如果我只是为 2D c 数组指定一个索引,它将充当逐列的顺序索引。那么,有没有什么方法可以快速访问整个列?在 c 和 Swift 中,largearray[][2]
无效. 但是我很好奇文档中是否没有提到某些技术,因为 Swift 显然会跟踪额外的信息。
我应该补充一点,我将使用 Accelerate 框架。因此,如果上述任何使用 Swift 数组的“奇怪”方式会导致海量数组的性能问题,请告诉我。
【问题讨论】:
我不能肯定地告诉你,因为我没有看过 Swift 数组的代码,但我很确定它们的行为更像 NSArray 而不是 C 数组。您可以有不同的长度,因为外部数组存储指向内部数组的指针。[1][3]
给出错误的原因是因为它在索引 1 处找到数组并尝试获取该数组的索引 3,但该数组只有 3 个项目。在 C 中,它可能会将 1,3 转换为线性数组中的索引并找到该对象,即使它在技术上是下一个数组中的第一个对象 ([2][0]
)
至于你的第二个问题,一个解决方案是var otherArray = largearray.map($0[2])
给你一个列数组返回...
所以这是我的问题的一部分。 Swift 数组是否只是一个数组数组,或者,如果使用固定数量的列,它是否只是内存中的一个逻辑连续数组?我实际上并不打算使用混合宽度,这只是一个奇怪的测试。但我想确保 Swift 在我需要时不必整理或做一些其他额外的数学运算来返回行。
@diatrevolo 谢谢!没想到探索地图功能。
啊,Swift 中的数组,就像@EmilioPelaez 提到的那样,是一个对象的集合,所以它更类似于NSArray
而不是float*
。
【参考方案1】:
Swift 数组与 c 数组有何不同
在 C 中,数组始终是一个连续的元素列表。在 Swift 中,数组是一种更为抽象的数据结构。您可以假设数据是如何使用 C 数组在内存中组织的,您甚至可以在给定基地址、元素大小和索引的情况下计算元素的地址。在 Swift 中,没有那么多。想想 Swift 的 Array
类型,就像你在 Objective-C 中的 NSArray
一样。它是一个有序的元素序列,提供类似数组的操作,但您不必担心它如何存储实际数据。
我不明白 Swift 怎么可能有混合的行长。
嗯,首先,您实际上是在查看一组数组。如果一个数组是一个对象,那么一个数组数组可能被实现为一个对象指针列表,而不是一系列连续的相同大小的列表。例如,您可以对 NSArray
执行相同的操作,因为 NSArray
中的每个项目都可以是任何类型的对象。
那么,有什么方法可以快速访问整个列吗?
您需要遍历数组中的项目,这些项目本身就是数组,并检查您感兴趣的“列”位置的元素。我认为没有比这更快的方法了那个。
【讨论】:
抓住了(和@EmilioPelaez 和@diatrevolo)。从性能的角度来看,我希望 Swift 基元数组更像原生 c 数组。我可以看到能够更轻松地填充和映射这些以及具有边界保护的优势。我只是希望在将它们“发送”到/从 Accelerate 函数时不会对性能造成太大影响。以上是关于Swift 数组与 c 数组有何不同的主要内容,如果未能解决你的问题,请参考以下文章