Heim  >  Artikel  >  Backend-Entwicklung  >  Was sind die Operationen für Zeiger in der Go-Sprache?

Was sind die Operationen für Zeiger in der Go-Sprache?

青灯夜游
青灯夜游Original
2023-01-04 10:30:293556Durchsuche

Die Go-Sprache verfügt nicht über Zeigerarithmetik. Die Syntax der Go-Sprache unterstützt keine Zeigerarithmetik und alle Zeiger werden innerhalb eines kontrollierbaren Bereichs verwendet. Tatsächlich kann die Go-Sprache den Zeiger jedoch indirekt über die Pointer()-Methode des unsicheren Pakets in eine Zahl vom Typ uintptr umwandeln Implementieren Sie Zeigerarithmetik.

Was sind die Operationen für Zeiger in der Go-Sprache?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.

Was genau ist ein Zeiger?

Speicher ist eine Reihe von Speichereinheiten mit Seriennummern. Variablen sind Spitznamen, die der Compiler den Speicheradressen zuweist.

Ein Zeiger ist ein Wert, der auf eine andere Speicheradressenvariable zeigt

Der Zeiger zeigt auf die Speicheradresse der Variablen, und der Zeiger ist wie die Speicheradresse des Variablenwerts

Werfen wir einen Blick auf einen Code snippet

func main() {
    a := 200
    b := &a
    *b++
    fmt.Println(a)
}

In der Hauptfunktion definieren wir in der ersten Zeile eine neue Variable a und weisen ihr den Wert 200 zu. Als nächstes definieren wir eine Variable b und weisen b die Adresse der Variablen a zu. Wir kennen die genaue Speicheradresse von a nicht, aber wir können die Adresse von a trotzdem in der Variablen b speichern.

Was sind die Operationen für Zeiger in der Go-Sprache?

Was sind die Operationen für Zeiger in der Go-Sprache?

Aufgrund der starken Typisierung von Go ist die dritte Codezeile vielleicht die aufdringlichste, aber wir möchten den in der a-Variablen gespeicherten Wert erhöhen .

Auf diese Weise müssen wir b dereferenzieren und stattdessen auf a verweisen, indem b dem Zeiger folgt.
Dann addieren wir 1 zum Wert und speichern ihn wieder an der in b hinterlegten Speicheradresse.

Die letzte Zeile gibt den Wert von a aus. Sie können sehen, dass der Wert von a auf 201 gestiegen ist Um

eine bestimmte Variable zu ändern, können wir

eine Zeigervariable erstellen Was sind die Operationen für Zeiger in der Go-Sprache?, die auf die Adresse der Variablen zeigt.

Im Gegensatz zu Zeigern in C/C++ können Was sind die Operationen für Zeiger in der Go-Sprache?Zeiger in der Go-Sprache nicht versetzt und bedient werden und sind sichere Zeiger

.

Um Zeiger in der Go-Sprache zu verstehen, müssen Sie zunächst drei Konzepte kennen: Zeigeradresse, Zeigertyp und Zeigerwert. Zeigeradresse und Zeigertyp

Zeigeroperationen in der Go-Sprache sind sehr einfach. Sie müssen sich nur zwei Symbole merken: & (Adresse abrufen) und * (Wert basierend auf Adresse abrufen).

Jede Variable hat zur Laufzeit eine Adresse, die den Speicherort der Variablen darstellt. In der Go-Sprache wird das &-Zeichen vor der Variablen verwendet, um „die Adresse“ der Variablen abzurufen.

Die Syntax zum Erfassen eines Variablenzeigers lautet wie folgt:
ptr := &v    // v的类型为T

Unter ihnen:

v: Die Variable, die die übernommene Adresse darstellt, der Typ ist T

ptr: Die Variable, die zum Empfangen verwendet wird Adresse, der Typ von ptr ist * T wird als Zeigertyp von T bezeichnet. * steht für Zeiger.

    func main() {
        a := 10
        b := &a
        fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
        fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
        fmt.Println(&b)                    // 0xc00000e018
    }
  • Zeigeroperator

  • 1. Wenn der Zeigeroperator ein L-Wert ist, können wir den Status des Zielobjekts aktualisieren; wenn es ein R-Wert ist, dient er dazu, den Status des Ziels zu erhalten .

func main() {
    x := 10
    var p *int = &x  //获取地址,保存到指针变量
    *p += 20        //用指针间接引用,并更新对象
    println(p, *p)  //输出指针所存储的地址,以及目标对象
}
Ausgabe:

0xc000040780 30
Was sind die Operationen für Zeiger in der Go-Sprache?2. Zeigertypen unterstützen Gleichheitsoperatoren, können jedoch keine Addition, Subtraktion und Typkonvertierung durchführen. Zwei Zeiger sind gleich, wenn sie auf dieselbe Adresse zeigen oder beide Null sind.

func main() {
    x := 10
    p := &x

    p++   //编译报错 invalid operation: p++ (non-numeric type *int)
    var p2 *int = p+1  //invalid operation: p + 1 (mismatched types *int and int)
    p2 = &x
    println(p == p2)   //指向同一地址
}

Sie können unsafe.Pointer verwenden, um den Zeiger in uintptr zu konvertieren und dann Additions- und Subtraktionsoperationen auszuführen, dies kann jedoch zu illegalem Zugriff führen.

Zeigerarithmetik

In vielen Golang-Programmen werden zwar Zeiger verwendet, Zeiger werden jedoch nicht addiert oder subtrahiert, was sich stark von C-Programmen unterscheidet. Golangs offizielles Einführungs-Lerntool (go-Tour) besagt sogar, dass Go keine Zeigerarithmetik unterstützt. Obwohl dies nicht wirklich der Fall ist, habe ich anscheinend noch nie Zeigerarithmetik in gewöhnlichen Go-Programmen gesehen (naja, ich weiß, dass Sie ungewöhnliche Programme schreiben möchten).

  • 但实际上,go 可以通过 unsafe.Pointer 来把指针转换为 uintptr 类型的数字,来间接实现指针运算。
  • 这里请注意,uintptr 是一种整数类型,而不是指针类型。

比如:

uintptr(unsafe.Pointer(&p)) + 1

就得到了 &p 的下一个字节的位置。然而,根据 《Go Programming Language》 的提示,我们最好直接把这个计算得到的内存地址转换为指针类型:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + 1))

因为 go 中是有垃圾回收机制的,如果某种 GC 挪动了目标值的内存地址,以整型来存储的指针数值,就成了无效的值。

同时也要注意,go 中对指针的 + 1,真的就只是指向了下一个字节,而 C 中 + 1 或者 ++ 考虑了数据类型的长度,会自动指向当前值结尾后的下一个字节(或者说,有可能就是下一个值的开始)。如果 go 中要想实现同样的效果,可以使用 unsafe.Sizeof 方法:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + unsafe.Sizeof(p)))

最后,另外一种常用的指针操作是转换指针类型。这也可以利用 unsafe 包来实现:

var a int64 = 1
(*int8)(unsafe.Pointer(&a))

如果你没有遇到过需要转换指针类型的需求,可以看看这个项目(端口扫描工具),其中构建 IP 协议首部的代码,就用到了指针类型转换。

【相关推荐:Go视频教程编程教学

Das obige ist der detaillierte Inhalt vonWas sind die Operationen für Zeiger in der Go-Sprache?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn