我正在修改矩阵的周长值,然后尝试递归到内部值。我希望我能够使用 matrix[1:3][1:3] 之类的东西访问内部值。事实并非如此,我对 Go 如何处理顺序括号的基本逻辑有点迷茫。
package main
import (
"fmt"
)
var m = [][]int{
[]int{0, 1, 2, 3},
[]int{4, 5, 6, 7},
[]int{8, 9, 10, 11},
[]int{12, 13, 14, 15},
}
我正在尝试访问上述矩阵(“内部”矩阵)中的值 5、6、9、10。
func main() {
inner := m[1:3][1:3]
fmt.Printf("%#v\n", inner)
// Expected Output: [][]int{
// []int{5, 6},
// []int{9, 10}
// }
// Actual Ouput: [][]int{
// []int{8, 9, 10, 11},
// []int{12, 13, 14, 15}
// }
inner = m[1:3]
fmt.Printf("%#v\n", inner)
// Output:
// [][]int{
// []int{4, 5, 6, 7},
// []int{8, 9, 10, 11}
// }
inner = innerMatrix(m)
fmt.Printf("%#v\n", inner)
// [][]int{
// []int{5, 6},
// []int{9, 10}
}
func innerMatrix(m [][]int) (inner [][]int) {
innerRows := m[1:3]
for _, row := range innerRows {
inner = append(inner, row[1:3])
}
return
}
函数 innerMatrix 能够产生我预期的输出。我不知道为什么 (1) m[1:3][1:3] 没有相同的效果,(2) 它似乎转换为 m[2 :4]。怎么回事?
最佳答案
当您在 Go 中创建一个子 slice 时,您可以将该子 slice 再次增长回原始 slice 的容量,例如:
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5}
b := a[1:3]
fmt.Printf("a[1:3]: %v\n", b)
c := b[1:3]
fmt.Printf("b[1:3]: %v\n", c)
}
哪些输出:
a[1:3]: [2 3]
b[1:3]: [3 4]
请注意 b 只有两个元素,但我们可以创建第二个和第三个元素的 slice ,因为它作为子 slice 的 slice 容量足够大,并且所有 slice 共享相同的底层数组。请参阅 this page 上“slice 内部结构”部分的最后一个示例
所以你的情况是 m[1:3] 等同于:
var m1 = [][]int{
[]int{4, 5, 6, 7}, // second element of m
[]int{8, 9, 10, 11}, // third element of m
}
和m[1:3][1:3]因此等价于m1[1:3],也就是等价于:
var m2 = [][]int{
[]int{8, 9, 10, 11}, // second element of m1
[]int{12, 13, 14, 15}, // "third" element of m1
}
“第三个”元素的出现只是因为 m 的容量大到足以容纳它,而且实际上确实容纳了它。如果 m 只有三个元素,这将导致 panic 。
换句话说,m[1:3][1:3]在这里完全等同于m[2:4],因为m[ 1:3][1:3] 给出了 m[1:3] 的第二个和第三个元素。用图表可能更容易理解:
m : []int{1, 2, 3, 4}
m[1:3] : []int{ 2, 3 }
m[1:3][1:3] : []int{ 3, 4}
m[2:4] : []int{ 3, 4}
作为一个过于简单化的例子,你可以想象方括号给出了紧靠它们左边的任何请求的元素,所以一个有点极端的例子:
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5}
b := a[1:5]
fmt.Printf("b: %v, a[1:5] : %v\n",
b, a[1:5])
c := b[1:4]
fmt.Printf("c: %v , a[1:5][1:4] : %v\n",
c, a[1:5][1:4])
d := c[1:3]
fmt.Printf("d: %v , a[1:5][1:4][1:3] : %v\n",
d, a[1:5][1:4][1:3])
e := d[1:2]
fmt.Printf("e: %v , a[1:5][1:4][1:3][1:2]: %v\n",
e, a[1:5][1:4][1:3][1:2])
}
哪些输出:
b: [2 3 4 5], a[1:5] : [2 3 4 5]
c: [3 4 5] , a[1:5][1:4] : [3 4 5]
d: [4 5] , a[1:5][1:4][1:3] : [4 5]
e: [5] , a[1:5][1:4][1:3][1:2]: [5]
关于go - 是否可以用括号对内部矩阵进行 slice ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55409679/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][