df = df.rolling(5).sum().diff().shift(-5)
print (df)
Open High Low Close Volume r_c
Date
2017-06-01 41000.0 77000.0 60000.0 71000.0 33891.0 NaN
2017-06-02 18000.0 -18000.0 7000.0 -29000.0 -30713.0 -0.044266
2017-06-05 -45000.0 -37000.0 -29000.0 -27000.0 16768.0 0.000876
2017-06-07 -35000.0 -22000.0 0.0 3000.0 -48895.0 0.013050
2017-06-08 34000.0 17000.0 9000.0 26000.0 -91274.0 0.010146
2017-06-09 -9000.0 -25000.0 -7000.0 -26000.0 73352.0 -0.023004
2017-06-12 8000.0 48000.0 21000.0 59000.0 -4643.0 0.037119
2017-06-13 NaN NaN NaN NaN NaN NaN
2017-06-14 NaN NaN NaN NaN NaN NaN
2017-06-15 NaN NaN NaN NaN NaN NaN
2017-06-16 NaN NaN NaN NaN NaN NaN
2017-06-19 NaN NaN NaN NaN NaN NaN
不应占用任何内存空间。但这两种结构有不同的尺寸。
[0]byte
那么为什么type bar2 struct {
A int
_ [0]byte
}
type bar3 struct {
_ [0]byte
A int
}
的位置在这里很重要?
顺便说一句,我使用[0]byte
方法来检查结构大小。请参阅full example。
答案 0 :(得分:5)
这是由于棘手的填充。
首先请允许我稍微重命名结构和字段,以便更容易讨论它们:
type bar1 struct {
A [0]byte
I int
}
type bar2 struct {
I int
A [0]byte
}
这当然不会改变Go Playground上可以验证的尺寸和偏移量:
bar1 size: 4
bar1.A offset: 0
bar1.I offset: 0
bar2 size: 8
bar2.I offset: 0
bar2.A offset: 4
类型[0]byte
的值的大小为零,因此在bar1
中完全无效,不为第一个字段(bar1.A
)保留任何空间,并将其布局为{0}的bar1.I
字段。
问题是:为什么编译器在第二种情况下(使用bar2
)也能做同样的事情?
字段必须具有必须位于为前一字段保留的存储区之后的地址。在第一种情况下,第一个字段bar1.A
具有0个大小,因此第二个字段可以具有0个偏移量,它不会“#34”重叠"第一场。
在bar2
的情况下,第二个字段不能具有与第一个字段重叠的地址(因此偏移量),因此其偏移量不能小于int
的大小,即4在32位体系结构的情况下为字节(在64位拱的情况下为8字节)。
这似乎还不错。但由于bar2.A
的大小为零,为什么结构bar2
的大小只能是:4个字节(或64位拱形中的8个)?
这是因为获取0大小的字段(和变量)的地址是完全有效的。好的,那又怎么样?
在bar2
的情况下,编译器必须插入4(或8)字节填充,否则取bar2.A
字段的地址会将指向存储区域之外保留为bar2
类型的值。
例如,无填充值为bar2
的地址可能为0x100
,大小为4,因此为struct值保留的内存的地址范围为{{ 1}}。 0x100 .. 0x103
的地址为bar2.A
,位于结构内存之外。如果是这个结构的数组(例如0x104
),如果数组从x [5]bar2
开始,0x100
的地址将是x[0]
,地址为0x100
将是x[0].A
,后续元素0x104
的地址也将是x[1]
,但这是另一个结构值的地址!不酷。
为避免这种情况,编译器会插入一个填充(根据拱形将为4或8个字节),因此取0x104
的地址不会导致地址超出结构的范围。 ; s内存,否则可能引发问题并引起有关垃圾收集的问题(例如,如果只保留bar2.A
的地址但不保留结构或其他指向它或其他字段的指针,整个结构不应该被垃圾收集,但由于没有指针指向其内存区域,所以这似乎是有效的)。插入的填充将是4(或8)个字节,因为Spec: Size and alignment guarantees:
对于结构类型的变量
bar2.A
:x
是unsafe.Alignof(x)
的每个字段unsafe.Alignof(x.f)
的所有值f
中的最大值,但至少x
。
如果是这样,添加额外的1
字段会使两个结构的大小相等:
int
确实,他们在32位拱门上都有8个字节(在64位拱门上有16个字节)(在Go Playground上试试):
type bar1 struct {
I int
A [0]byte
X int
}
type bar2 struct {
A [0]byte
I int
X int
}
请参阅相关问题:Struct has different size if the field order is different
答案 1 :(得分:1)
原因是“漏洞”:
孔是编译器添加的未使用空间,以确保 以下字段或元素相对于开头正确对齐 结构或数组[1]
例如(基于操场上使用的任何硬件的数字):
struct {bool; float64; int16} // 24 bytes
struct {float64; bool; int16} // 16 bytes
您可以使用以下方法验证结构的布局:
[1] p354 Donovan,Kernighan,AD,BK,2016。GO编程语言。第1版。纽约:Addison-Wesley。