为什么使用数组而不是切片? [英] Why use arrays instead of slices?

查看:156
本文介绍了为什么使用数组而不是切片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读Go,并且难以想象这个基本问题。

在Go中,很明显切片更加灵活,并且可以通常在需要数据序列时用于代替数组。

阅读大部分文档时,他们似乎鼓励开发人员使用片而不是数组。我感受到的印象是创作者可以简单地将数组设计为可调整大小,并且在没有整个切片部分的情况下完成。事实上,这样的设计可以让语言更容易理解,甚至可以鼓励更多的惯用代码。

那么为什么创作者首先允许数组呢? ?何时会使用数组而不是切片?是否曾经有过使用数组而超越切片的情况?



当我查阅官方文档(http://golang.org/doc/effective_go.html#arrays ),我发现的唯一有用的部分是:


在规划内存的详细布局时,数组非常有用,
有时可以帮助避免分配,但主要是构建块
对于切片。


他们继续讨论数组是如何像数值一样昂贵的,以及如何用指针模拟C样式的行为。即便如此,他们仍然在数组部分中提出了明确的建议:


但即使这种风格不是惯用的Go。


那么,规划内存的详细布局或帮助避免分配的真实例子是什么?切片将不适合?

解决方案

正如Akavall所说,数组是可散列的。这意味着它们可以用作地图的关键。



它们也通过价值传递。每次你将它传递给一个函数,或者将它分配给另一个变量,它就会完整地拷贝它。



它们可以通过编码/二进制序列化。

它们也可以用来控制内存布局。因为它不是一个引用,所以当它被放置在一个结构体中时,它将分配那么多的内存作为结构体的一部分,而不是像一个切片那样放置一个指针等价物。



底线,除非您知道自己在做什么,否则不要使用数组。





Hashable / serializable都很好用,但我不确定它们是否真的有吸引力


如果你想拥有md5哈希映射,你会怎么做?无法使用字节片段,因此您需要这样做来解决类型系统问题:

  // 16字节
类型hashableMd5结构{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p字节}

然后为它创建一个序列化函数。 Hashable数组意味着你可以称它为[16]字节。


听起来像接近C的malloc,sizeof


不,与malloc或sizeof无关。这些是分配内存并获得变量的大小。



然而,CGo是另一个用例。 cgo命令创建与其对应的C类型具有相同内存布局的类型。要做到这一点,它有时需要插入未命名的数组用于填充。


如果问题可以用...零/无意义的性能损失来解决使用切片...

数组还可以防止indirects使某些类型的代码更快。当然这是一个小小的优化,几乎在所有情况下都是微不足道的。


I have been reading up on Go, and got stumped thinking about this fundamental question.

In Go, it is quite clear that slices are more flexible, and can generally be used in place of arrays when you need a sequence of data.

Reading most of the documentation, they seem to be encouraging developers to just use slices instead of arrays. The impression I get feels like the creators could have simply designed arrays to be resize-able, and done without the entire slices section. In fact, such a design would have made the language even easier to understand, and perhaps even encouraged more idiomatic code.

So why did the creators allow arrays in the first place? When would arrays ever be used instead of slices? Is there ever a situation where the use of arrays over slices will be compelling?

When I consulted the official documentation (http://golang.org/doc/effective_go.html#arrays), the only useful part I found was:

Arrays are useful when planning the detailed layout of memory and sometimes can help avoid allocation, but primarily they are a building block for slices.

They went on to talk about how arrays are expensive as values, and how to simulate C-style behavior with pointer. Even then, they ended the array section with a clear recommendation:

But even this style isn't idiomatic Go. Use slices instead.

So, what are some real examples of "planning the detailed layout of memory" or "help avoid allocation" that slices would be unsuited for?

解决方案

As said by Akavall, arrays are hashable. That means they can be used as a key to a map.

They are also pass by value. Each time you pass it to a function it to a function or assign it to another variable it makes a complete copy of it.

They can be serialized by encoding/binary.

They also can be used to control memory layout. Since it is not a reference, when it is placed in a struct, it will allocate that much memory as part of the struct instead of putting the equivalent of a pointer there like a slice would.

Bottom line, don't use an array unless you know what you are doing.


Hashable/serializable are all nice to have, but I'm just not sure if they are indeed that compelling to have

What would you do if you wanted to have a map of md5 hashes? Can't use a byte slice so you would need to do something like this to get around the type system:

// 16 bytes
type hashableMd5 struct {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p byte}

Then create a serialization function for it. Hashable arrays mean that you can just call it a [16]byte.

Sounds like getting closer to C's malloc, sizeof

Nope, that has nothing to do with malloc or sizeof. Those are to allocate memory and get the size of a variable.

However, CGo is another use case for this. The cgo command creates types that have the same memory layout as their corresponding C types. To do this, it sometimes needs to insert unnamed arrays for padding.

If problems can be solved with ... nil/insignificant performance penalty using slices ...

Arrays also prevent indirects making certain types of code faster. Of course this is such a minor optimization that this is insignificant in nearly all cases.

这篇关于为什么使用数组而不是切片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆