如何判断两个切片是否引用同一块内存?

huangapple go评论81阅读模式
英文:

How to find if two slices are references to same memory?

问题

考虑以下示例:

sliceA := make([]byte, 10)
sliceB := make([]byte, 10)

// sliceA和sliceB引用不同的内存,
// 最终可能包含相同的数据

sliceC := sliceA[:]

// sliceC引用与sliceA相同的内存
sliceD := sliceA[1:2]; sliceE := sliceA[4:5]
// 断言sliceD和sliceE共享相同的内存块

有没有办法检查两个切片是否引用(或不引用)相同的内存?

编辑

我想要比较的切片可能不指向相同的底层内存块的段。

英文:

Consider this example:

sliceA := make([]byte, 10)
sliceB := make([]byte, 10)

// sliceA and sliceB are referencing different memory,
// witch eventually may contain same data

sliceC := sliceA[:]

// sclieC references same memory as sliceA
sliceD := sliceA[1:2]; sliceE := sliceA[4:5]
// assert that sliceD and sliceE share same block of memory

Is there any way to check that 2 slices are references (or not) to the same memory?

EDIT

The slices that I want to compare might not point to the same segment of underlying block of memory.

答案1

得分: 6

你可以通过导入"reflect"来测试地址:

same := reflect.ValueOf(sliceA).Pointer() == reflect.ValueOf(sliceC).Pointer()

示例

package main

import (
    "fmt"
    "reflect"
)

func main() {
    sliceA := make([]byte, 10)
    sliceC := sliceA[1:]
    sliceD := sliceA[1:]
    fmt.Println(reflect.ValueOf(sliceC).Pointer() == reflect.ValueOf(sliceD).Pointer())
}

这个测试的是切片的起始位置,而不仅仅是底层数组。

英文:

You can test the addresses by importing "reflect" :

same := reflect.ValueOf(sliceA).Pointer() == reflect.ValueOf(sliceC).Pointer()

Example :

package main

import (
	"fmt"
	"reflect"
)

func main() {
	sliceA := make([]byte, 10)
	sliceC := sliceA[1:]
	sliceD := sliceA[1:]
	fmt.Println(reflect.ValueOf(sliceC).Pointer() == reflect.ValueOf(sliceD).Pointer())
}

This tests the position of the slice's start, not just the underlying array.

答案2

得分: 4

两个非空实例a和b,类型为[]T,如果它们共享相同的后备数组,则满足以下条件:

&a[cap(a)-1] == &b[cap(b)-1]

请注意,在测试之前可能需要重新切片a和/或b。

英文:

Two non nil instances, a and b, of type []T, share the same backing array iff

&a[cap(a)-1] == &b[cap(b)-1]

Note that it may be necessary to reslice a and or b before the test.

答案3

得分: 0

@canni的问题和@jnml和@dystroy的答案令人困惑。

这是简化版本。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    sliceA := make([]byte, 10)
    sliceD := sliceA[1:2]
    sliceE := sliceA[4:5]
    // 断言sliceD和sliceE共享同一块内存
    canni := true
    jnml := &sliceD[:cap(sliceD)][cap(sliceD)-1] == &sliceE[:cap(sliceE)][cap(sliceE)-1]
    dystroy := reflect.ValueOf(sliceD).Pointer() == reflect.ValueOf(sliceE).Pointer()
    // true true false
    fmt.Println(canni, jnml, dystroy)
}

输出:

true true false
英文:

@canni's question and @jnml's and @dystroy's answers are confused and confusing.

Here's the simple version.

package main

import (
	"fmt"
	"reflect"
)

func main() {
	sliceA := make([]byte, 10)
	sliceD := sliceA[1:2]
	sliceE := sliceA[4:5]
	// assert that sliceD and sliceE share same block of memory
	canni := true
	jnml := &sliceD[:cap(sliceD)][cap(sliceD)-1] == &sliceE[:cap(sliceE)][cap(sliceE)-1]
	dystroy := reflect.ValueOf(sliceD).Pointer() == reflect.ValueOf(sliceE).Pointer()
	// true true false
	fmt.Println(canni, jnml, dystroy)
}

Output:

true true false

huangapple
  • 本文由 发表于 2013年5月30日 22:25:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/16838794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定