如何创建一个固定大小的对象数组

时间:2022-05-23 01:54:04

In Swift, I am trying to create an array of 64 SKSpriteNode. I want first to initialize it empty, then I would put Sprites in the first 16 cells, and the last 16 cells (simulating an chess game).

在Swift中,我尝试创建一个64 SKSpriteNode的数组。我想先初始化它为空,然后在前16个单元格和后16个单元格中放入精灵(模拟象棋游戏)。

From what I understood in the doc, I would have expect something like:

从我在《宣言》中所了解到的,我可能会期待:

var sprites = SKSpriteNode()[64];

var精灵= SKSpriteNode()[64];

or

var sprites4 : SKSpriteNode[64];

var sprites4:SKSpriteNode[64];

But it doesn't work. In the second case, I get an error saying: "Fixed-length arrays are not yet supported". Can that be real? To me that sounds like a basic feature. I need to access the element directly by their index.

但它不工作。在第二种情况下,我得到一个错误消息:“不支持固定长度的数组”。这是真的吗?对我来说,这听起来像是一个基本特征。我需要通过它们的索引直接访问元素。

7 个解决方案

#1


101  

Fixed-length arrays are not yet supported. What does that actually mean? Not that you can't create an array of n many things — obviously you can just do let a = [ 1, 2, 3 ] to get an array of three Ints. It means simply that array size is not something that you can declare as type information.

不支持固定长度的数组。这到底是什么意思?并不是说你不能创建一个包含n个元素的数组——显然你可以让a =[1,2,3]得到一个包含3个int的数组。它仅仅意味着数组大小不是可以声明为类型信息的东西。

If you want an array of nils, you'll first need an array of an optional type — [SKSpriteNode?], not [SKSpriteNode] — if you declare a variable of non-optional type, whether it's an array or a single value, it cannot be nil. (Also note that [SKSpriteNode?] is different from [SKSpriteNode]?... you want an array of optionals, not an optional array.)

如果你想要一组nils,你首先需要一个可选类型的数组- [SKSpriteNode?[],而不是[SKSpriteNode] -如果您声明一个非可选类型的变量,无论是数组还是单个值,它都不能是nil。(也请注意,[SKSpriteNode ?与[SKSpriteNode]不同吗?你想要一个选项数组,而不是一个可选数组。

Swift is very explicit by design about requiring that variables be initialized, because assumptions about the content of uninitialized references are one of the ways that programs in C (and some other languages) can become buggy. So, you need to explicitly ask for an [SKSpriteNode?] array that contains 64 nils:

Swift通过要求对变量进行初始化的设计非常明确,因为关于未初始化引用内容的假设是C语言(以及其他一些语言)中的程序可能出现bug的一种方式。那么,您需要明确地要求一个[SKSpriteNode?]包含64个nils的阵列:

var sprites = [SKSpriteNode?](repeating: nil, count: 64)

This actually returns a [SKSpriteNode?]?, though: an optional array of optional sprites. (A bit odd, since init(count:,repeatedValue:) shouldn't be able to return nil.) To work with the array, you'll need to unwrap it. There's a few ways to do that, but in this case I'd favor optional binding syntax:

这实际上返回一个[SKSpriteNode?]?但是:一个可选的精灵数组。(有点奇怪,因为init(count:,repeatedValue:)不应该能够返回nil。)要使用数组,需要展开它。有几种方法可以做到这一点,但在这种情况下,我更喜欢可选绑定语法:

if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
    sprites[0] = pawnSprite
}

#2


51  

The best you are going to be able to do for now is create an array with an initial count repeating nil:

你现在能做的最好的事情就是创建一个数组,初始计数重复为nil:

var sprites = [SKSpriteNode?](count: 64, repeatedValue: nil)

You can then fill in whatever values you want.

然后您可以填写任何您想要的值。


In Swift 3.0 :

在斯威夫特3.0:

var sprites = [SKSpriteNode?](repeating: nil, count: 64)

#3


4  

Declare an empty SKSpriteNode, so there won't be needing for unwraping

声明一个空的SKSpriteNode,这样就不需要展开

var sprites = [SKSpriteNode](count: 64, repeatedValue: SKSpriteNode())

#4


2  

For now, semantically closest one would be a tuple with fixed number of elements.

就目前而言,语义上最接近的是一个元素数量固定的元组。

typealias buffer = (
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode)

But this is (1) very uncomfortable to use and (2) memory layout is undefined. (at least unknown to me)

但是这(1)使用起来非常不舒服(2)内存布局没有定义。(至少我不知道)

#5


1  

Swift 4

You can somewhat think about it as array of object vs. array of references.

你可以把它想象成对象数组和引用数组。

  • [SKSpriteNode] must contain actual objects
  • [SKSpriteNode]必须包含实际的对象
  • [SKSpriteNode?] can contain either references to objects, or nil
  • [SKSpriteNode ?可以包含对对象的引用,也可以包含nil

Examples

例子

  1. Creating an array with 64 default SKSpriteNode:

    创建一个带有64默认SKSpriteNode的数组:

    var sprites = [SKSpriteNode](repeatElement(SKSpriteNode(texture: nil),
                                               count: 64))
    
  2. Creating an array with 64 empty slots (a.k.a optionals):

    创建一个有64个空槽的数组(a.k。可选):

    var optionalSprites = [SKSpriteNode?](repeatElement(nil,
                                          count: 64))
    
  3. Converting an array of optionals into an array of objects (collapsing [SKSpriteNode?] into [SKSpriteNode]):

    将选项数组转换为对象数组(折叠[SKSpriteNode?]到[SKSpriteNode]):

    let flatSprites = optionalSprites.flatMap { $0 }
    

    The count of the resulting flatSprites depends on the count of objects in optionalSprites: empty optionals will be ignored, i.e. skipped.

    产生的平面精灵的计数取决于optionalsprite中对象的计数:空的选项将被忽略,即跳过。

#6


0  

This question has already been answered, but for some extra information at the time of Swift 4:

这个问题已经得到了回答,但是对于Swift 4时的一些额外信息:

In case of performance, you should reserve memory for the array, in case of dynamically creating it, such as adding elements with Array.append().

对于性能,在动态创建数组时,应该为数组预留内存,例如使用array .append()添加元素。

var array = [SKSpriteNode]()
array.reserveCapacity(64)

for _ in 0..<64 {
    array.append(SKSpriteNode())
}

If you know the minimum amount of elements you'll add to it, but not the maximum amount, you should rather use array.reserveCapacity(minimumCapacity: 64).

如果您知道要添加的元素的最小数量,但不知道最大数量,您应该使用数组。reserveCapacity(minimumCapacity:64)。

#7


-2  

One thing you could do would be to create a dictionary. Might be a little sloppy considering your looking for 64 elements but it gets the job done. Im not sure if its the "preferred way" to do it but it worked for me using an array of structs.

你可以做的一件事就是创建一个字典。考虑到寻找64个元素可能有点草率,但它完成了任务。我不确定这是否是“首选的方式”,但它对我来说是适用的,使用了一系列结构体。

var tasks = [0:[forTasks](),1:[forTasks](),2:[forTasks](),3:[forTasks](),4:[forTasks](),5:[forTasks](),6:[forTasks]()]

#1


101  

Fixed-length arrays are not yet supported. What does that actually mean? Not that you can't create an array of n many things — obviously you can just do let a = [ 1, 2, 3 ] to get an array of three Ints. It means simply that array size is not something that you can declare as type information.

不支持固定长度的数组。这到底是什么意思?并不是说你不能创建一个包含n个元素的数组——显然你可以让a =[1,2,3]得到一个包含3个int的数组。它仅仅意味着数组大小不是可以声明为类型信息的东西。

If you want an array of nils, you'll first need an array of an optional type — [SKSpriteNode?], not [SKSpriteNode] — if you declare a variable of non-optional type, whether it's an array or a single value, it cannot be nil. (Also note that [SKSpriteNode?] is different from [SKSpriteNode]?... you want an array of optionals, not an optional array.)

如果你想要一组nils,你首先需要一个可选类型的数组- [SKSpriteNode?[],而不是[SKSpriteNode] -如果您声明一个非可选类型的变量,无论是数组还是单个值,它都不能是nil。(也请注意,[SKSpriteNode ?与[SKSpriteNode]不同吗?你想要一个选项数组,而不是一个可选数组。

Swift is very explicit by design about requiring that variables be initialized, because assumptions about the content of uninitialized references are one of the ways that programs in C (and some other languages) can become buggy. So, you need to explicitly ask for an [SKSpriteNode?] array that contains 64 nils:

Swift通过要求对变量进行初始化的设计非常明确,因为关于未初始化引用内容的假设是C语言(以及其他一些语言)中的程序可能出现bug的一种方式。那么,您需要明确地要求一个[SKSpriteNode?]包含64个nils的阵列:

var sprites = [SKSpriteNode?](repeating: nil, count: 64)

This actually returns a [SKSpriteNode?]?, though: an optional array of optional sprites. (A bit odd, since init(count:,repeatedValue:) shouldn't be able to return nil.) To work with the array, you'll need to unwrap it. There's a few ways to do that, but in this case I'd favor optional binding syntax:

这实际上返回一个[SKSpriteNode?]?但是:一个可选的精灵数组。(有点奇怪,因为init(count:,repeatedValue:)不应该能够返回nil。)要使用数组,需要展开它。有几种方法可以做到这一点,但在这种情况下,我更喜欢可选绑定语法:

if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
    sprites[0] = pawnSprite
}

#2


51  

The best you are going to be able to do for now is create an array with an initial count repeating nil:

你现在能做的最好的事情就是创建一个数组,初始计数重复为nil:

var sprites = [SKSpriteNode?](count: 64, repeatedValue: nil)

You can then fill in whatever values you want.

然后您可以填写任何您想要的值。


In Swift 3.0 :

在斯威夫特3.0:

var sprites = [SKSpriteNode?](repeating: nil, count: 64)

#3


4  

Declare an empty SKSpriteNode, so there won't be needing for unwraping

声明一个空的SKSpriteNode,这样就不需要展开

var sprites = [SKSpriteNode](count: 64, repeatedValue: SKSpriteNode())

#4


2  

For now, semantically closest one would be a tuple with fixed number of elements.

就目前而言,语义上最接近的是一个元素数量固定的元组。

typealias buffer = (
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
    SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode)

But this is (1) very uncomfortable to use and (2) memory layout is undefined. (at least unknown to me)

但是这(1)使用起来非常不舒服(2)内存布局没有定义。(至少我不知道)

#5


1  

Swift 4

You can somewhat think about it as array of object vs. array of references.

你可以把它想象成对象数组和引用数组。

  • [SKSpriteNode] must contain actual objects
  • [SKSpriteNode]必须包含实际的对象
  • [SKSpriteNode?] can contain either references to objects, or nil
  • [SKSpriteNode ?可以包含对对象的引用,也可以包含nil

Examples

例子

  1. Creating an array with 64 default SKSpriteNode:

    创建一个带有64默认SKSpriteNode的数组:

    var sprites = [SKSpriteNode](repeatElement(SKSpriteNode(texture: nil),
                                               count: 64))
    
  2. Creating an array with 64 empty slots (a.k.a optionals):

    创建一个有64个空槽的数组(a.k。可选):

    var optionalSprites = [SKSpriteNode?](repeatElement(nil,
                                          count: 64))
    
  3. Converting an array of optionals into an array of objects (collapsing [SKSpriteNode?] into [SKSpriteNode]):

    将选项数组转换为对象数组(折叠[SKSpriteNode?]到[SKSpriteNode]):

    let flatSprites = optionalSprites.flatMap { $0 }
    

    The count of the resulting flatSprites depends on the count of objects in optionalSprites: empty optionals will be ignored, i.e. skipped.

    产生的平面精灵的计数取决于optionalsprite中对象的计数:空的选项将被忽略,即跳过。

#6


0  

This question has already been answered, but for some extra information at the time of Swift 4:

这个问题已经得到了回答,但是对于Swift 4时的一些额外信息:

In case of performance, you should reserve memory for the array, in case of dynamically creating it, such as adding elements with Array.append().

对于性能,在动态创建数组时,应该为数组预留内存,例如使用array .append()添加元素。

var array = [SKSpriteNode]()
array.reserveCapacity(64)

for _ in 0..<64 {
    array.append(SKSpriteNode())
}

If you know the minimum amount of elements you'll add to it, but not the maximum amount, you should rather use array.reserveCapacity(minimumCapacity: 64).

如果您知道要添加的元素的最小数量,但不知道最大数量,您应该使用数组。reserveCapacity(minimumCapacity:64)。

#7


-2  

One thing you could do would be to create a dictionary. Might be a little sloppy considering your looking for 64 elements but it gets the job done. Im not sure if its the "preferred way" to do it but it worked for me using an array of structs.

你可以做的一件事就是创建一个字典。考虑到寻找64个元素可能有点草率,但它完成了任务。我不确定这是否是“首选的方式”,但它对我来说是适用的,使用了一系列结构体。

var tasks = [0:[forTasks](),1:[forTasks](),2:[forTasks](),3:[forTasks](),4:[forTasks](),5:[forTasks](),6:[forTasks]()]