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 数组有何不同的主要内容,如果未能解决你的问题,请参考以下文章

字符串与 Pascal 中的大量(数组)字符有何不同?

MATLAB 中的单元格和数组的连接和索引有何不同?

将 Swift 字符串数组转换为 C 字符串数组指针

将 Swift 字符串数组转换为 C 字符串数组指针

iOS Swift:如何根据特定属性查找不同类型数组的唯一成员

Swift中对C语言接口缓存的使用以及数组字符串转为指针类型的方法