mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 00:43:26 +08:00
精校:4.8-5.1
This commit is contained in:
@@ -8,14 +8,18 @@
|
||||
|
||||
Go 语言的取地址符是 `&`,放到一个变量前使用就会返回相应变量的内存地址。
|
||||
|
||||
下面的代码片段(Example 4.9 [pointer.go](examples/chapter_4/pointer.go))可能输出 `An integer: 5, its location in memory: 0x6b0820`(这个值随着你每次运行程序而变化)。
|
||||
|
||||
var i1 = 5
|
||||
fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1)
|
||||
下面的代码片段(示例 4.9 [pointer.go](examples/chapter_4/pointer.go))可能输出 `An integer: 5, its location in memory: 0x6b0820`(这个值随着你每次运行程序而变化)。
|
||||
|
||||
```go
|
||||
var i1 = 5
|
||||
fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1)
|
||||
```
|
||||
|
||||
这个地址可以存储在一个叫做指针的特殊数据类型中,在本例中这是一个指向 int 的指针,即 `i1`:此处使用 *int 表示。如果我们想调用指针 intP,我们可以这样声明它:
|
||||
|
||||
var intP *int
|
||||
|
||||
```go
|
||||
var intP *int
|
||||
```
|
||||
|
||||
然后使用 `intP = &i1` 是合法的,此时 intP 指向 i1。
|
||||
|
||||
@@ -39,20 +43,22 @@ intP 存储了 i1 的内存地址;它指向了 i1 的位置,它引用了变
|
||||
|
||||
现在,我们应当能理解 pointer.go 中的整个程序和他的输出:
|
||||
|
||||
Example 4.21 [pointer.go](examples/chapter_4/pointer.go):
|
||||
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
var i1 = 5
|
||||
fmt.Printf("An integer: %d, its location in memory: %p\n", i1, &i1)
|
||||
var intP *int
|
||||
intP = &i1
|
||||
fmt.Printf("The value at memory location %p is %d\n", intP, *intP)
|
||||
}
|
||||
示例 4.21 [pointer.go](examples/chapter_4/pointer.go):
|
||||
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
var i1 = 5
|
||||
fmt.Printf("An integer: %d, its location in memory: %p\n", i1, &i1)
|
||||
var intP *int
|
||||
intP = &i1
|
||||
fmt.Printf("The value at memory location %p is %d\n", intP, *intP)
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
|
||||
An integer: 5, its location in memory: 0x24f0820
|
||||
The value at memory location 0x24f0820 is 5
|
||||
|
||||
@@ -64,18 +70,20 @@ Example 4.21 [pointer.go](examples/chapter_4/pointer.go):
|
||||
|
||||
它展示了分配一个新的值给 *p 并且更改这个变量自己的值(这里是一个字符串)。
|
||||
|
||||
Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
|
||||
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
s := "good bye"
|
||||
var p *string = &s
|
||||
*p = "ciao"
|
||||
fmt.Printf("Here is the pointer p: %p\n", p) // prints address
|
||||
fmt.Printf("Here is the string *p: %s\n", *p) // prints string
|
||||
fmt.Printf("Here is the string s: %s\n", s) // prints same string
|
||||
}
|
||||
示例 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
s := "good bye"
|
||||
var p *string = &s
|
||||
*p = "ciao"
|
||||
fmt.Printf("Here is the pointer p: %p\n", p) // prints address
|
||||
fmt.Printf("Here is the string *p: %s\n", *p) // prints string
|
||||
fmt.Printf("Here is the string s: %s\n", s) // prints same string
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
@@ -92,10 +100,12 @@ Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
|
||||
**注意事项**
|
||||
|
||||
你不能得到一个文字或常量的地址,例如:
|
||||
|
||||
const i = 5
|
||||
ptr := &i //error: cannot take the address of i
|
||||
ptr2 := &10 //error: cannot take the address of 10
|
||||
|
||||
```go
|
||||
const i = 5
|
||||
ptr := &i //error: cannot take the address of i
|
||||
ptr2 := &10 //error: cannot take the address of 10
|
||||
```
|
||||
|
||||
所以说,Go 语言和 C、C++ 以及 D 语言这些低级(系统)语言一样,都有指针的概念。但是对于经常导致 C 语言内存泄漏继而程序崩溃的指针运算(所谓的指针算法,如:`pointer+2`,移动指针指向字符串的字节数或数组的某个位置)是不被允许的。Go 语言中的指针保证了内存安全,更像是 Java、C# 和 VB.NET 中的引用。
|
||||
|
||||
@@ -111,15 +121,17 @@ Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
|
||||
|
||||
对一个空指针的反向引用是不合法的,并且会使程序崩溃:
|
||||
|
||||
Example 4.23 [testcrash.go](examples/chapter_4/testcrash.go):
|
||||
|
||||
package main
|
||||
func main() {
|
||||
var p *int = nil
|
||||
*p = 0
|
||||
}
|
||||
// in Windows: stops only with: <exit code="-1073741819" msg="process crashed"/>
|
||||
// runtime error: invalid memory address or nil pointer dereference
|
||||
示例 4.23 [testcrash.go](examples/chapter_4/testcrash.go):
|
||||
|
||||
```go
|
||||
package main
|
||||
func main() {
|
||||
var p *int = nil
|
||||
*p = 0
|
||||
}
|
||||
// in Windows: stops only with: <exit code="-1073741819" msg="process crashed"/>
|
||||
// runtime error: invalid memory address or nil pointer dereference
|
||||
```
|
||||
|
||||
**问题 4.2** 列举 Go 语言中 * 号的所有用法。
|
||||
|
||||
|
Reference in New Issue
Block a user