当前位置: 首页 > 面试题库 >

在Go中创建2D切片的简洁方法是什么?

苏波涛
2023-03-14
问题内容

我正在通过“围棋之旅”学习围棋。其中的一项练习要求我创建包含的2D
dy行和dx列的二维切片uint8。我目前有效的方法是:

a:= make([][]uint8, dy)       // initialize a slice of dy slices
for i:=0;i<dy;i++ {
    a[i] = make([]uint8, dx)  // initialize a slice of dx unit8 in each of dy slices
}

我认为遍历每个切片以初始化它太冗长。而且,如果切片具有更大的尺寸,则代码将变得笨拙。Go中有没有一种初始化2D(或n维)切片的简洁方法?


问题答案:

没有一种更简洁的方法,您所做的就是“正确”的方法。因为切片始终是一维的,但可以组成更高维度的对象。

您可以简化的一件事是使用for range构造:

a := make([][]uint8, dy)
for i := range a {
    a[i] = make([]uint8, dx)
}

另请注意,如果您使用复合文字初始化切片,则会获得“免费”,例如:

a := [][]uint8{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]

是的,这似乎有其局限性,因为您似乎必须列举所有要素。但是有一些技巧,即您不必枚举所有值,只需枚举不是切片元素类型的零值的那些值即可。。

例如,如果您想要一个前10个元素为零的切片,然后跟随12,则可以这样创建切片:

b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]

还要注意,如果使用数组而不是slice,则可以很容易地创建它:

c := [5][5]uint8{}
fmt.Println(c)

输出为:

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

如果是数组,则不必遍历“外部”数组并初始化“内部”数组,因为数组不是描述符而是值。请参阅博客文章数组,切片(和字符串):有关更多详细信息的“追加”机制

在Go Playground上尝试示例。



 类似资料:
  • 问题内容: 是否有比简单的if-else更好的否定Java布尔值的方法? 问题答案:

  • 问题内容: 我在Go中建立了一个简单的队列。它使用内部切片来跟踪其元素。通过附加到切片将元素推入队列。我想通过删除中的第一个元素来实现。 在许多其他语言中,“弹出”列表的第一个元素是一个单行,这使我相信下面的实现是草率而冗长的。有没有更好的办法? 请注意,如果,我会感到恐慌。我不检查界限不是疏忽大意。 问题答案: 你尝试过这些吗? 从队列弹出 从堆栈弹出 推 来自:https : //code.g

  • 我在Go中构建了一个简单的队列。它使用内部切片来跟踪其元素。元素通过附加到切片而被推送到队列中。我想实现。 在许多其他语言中,“弹出”列表的第一个元素是一行,这使我相信下面的实现是草率和冗长的。有更好的办法吗? 请注意,如果

  • 问题内容: Swift中的切片是什么,它与数组有何不同? 从文档中,下标(Range)的类型签名为: 为什么不返回另一个而不是一个? 看起来我可以将切片与数组连接起来: 但这会产生错误: 无法找到接受提供的参数的“下标”的重载 什么是切片? 问题答案: 切片指向数组。当数组已经存在并且切片只能描述其所需部分时,再也没有必要制作另一个数组。 加法会导致隐式强制,因此可以正常工作。为了使您的作业正常进

  • Swift中的切片是什么?它与数组有何不同? 从文档中可以看出,下标(范围)的类型签名是: 为什么不返回另一个而不是? 看起来我可以将一个片与一个数组连接起来: 但这会产生错误: 找不到接受所提供参数的“subscript”的重载 什么是切片?

  • 问题内容: 假设我要编写一个在切片中查找值的函数 我直观地想写: 但是我无法通过Go做到这一点。我可以与 这样就可以了,但是在我的真实代码中,事情变得更加复杂(我需要进行slices [from:end]等),append等…,如果我在接口中重新定义了所有这些代码,我最终会拥有很多代码。有没有更好的办法? 问题答案: 您可以使用反射。我为项目编写了此函数,请随时使用它: