Understand addressable and non addressable in go

Time:2022-5-7
catalogue
  • 1. What is addressable?
  • 2. What are addressable?
    • Variable: & X
    • Pointer: & * x
    • Array element index: & A [0]
    • section
    • Slice element index: & s [1]
    • Combined literal: & struct {X type} {value}
  • 3. What are not addressable?
    • constant
    • character string
    • Function or method
    • Basic type literal
    • Elements in map
    • array literal

1. What is addressable?

Objects that can be addressed directly using the & operator are addressable(Addressable)。 For example, the following example

?
1
2
3
4
5
func main() {
    name := "iswbm"
    fmt.Println(&name) 
    // output: 0xc000010200
}

No error will be reported when the program runs. Please explainname This variable is addressable.

But I can’t say“iswbm“This string is addressable.

iswbm“It’s a string. All strings are immutable and not addressable, which will be introduced later.

Before we start the introduction one by one, let’s talk about the conclusion

  • Pointer addressable: & profile {}
  • Variable addressable: Name: = profile {}
  • Literal quantity cannot be addressed: profile {}

2. What are addressable?

Variable: & X

?
1
2
3
4
5
func main() {
    name := "iswbm"
    fmt.Println(&name) 
    // output: 0xc000010200
}

Pointer: & * x

?
1
2
3
4
5
6
7
8
type Profile struct {
    Name string
}
 
func main() {
    fmt.Println(unsafe.Pointer(&Profile{Name: "iswbm"}))
    // output: 0xc000108040
}

Array element index: & A [0]

?
1
2
3
4
5
func main() {
    s := [...]int{1,2,3}
    fmt.Println(&s[0])
    // output: xc0000b4010
}

section

?
1
2
3
func main() {
    fmt.Println([]int{1, 2, 3}[1:])
}

Slice element index: & s [1]

?
1
2
3
4
5
func main() {
    s := make([]int , 2, 2)
    fmt.Println(&s[0]) 
    // output: xc0000b4010
}

Combined literal: & struct {X type} {value}

All combined literals are not addressable, as shown below

?
1
2
3
4
5
6
7
8
9
10
11
12
type Profile struct {
    Name string
}
 
func new() Profile {
    return Profile{Name: "iswbm"}
}
 
func main() {
    fmt.Println(&new())
    // cannot take the address of new()
}

Pay attention to the difference between the above writing and this writing. The following writing represents different meanings. The & is not the operation of taking the address, but the pointer of instantiating a structure.

?
1
2
3
4
5
6
7
type Profile struct {
    Name string
}
 
func main() {
    fmt.Println(&Profile{Name: "iswbm"}) // ok
}

Although combined literals are not addressable, the field properties of combined literals can be addressed (direct access)

?
1
2
3
4
5
6
7
8
9
10
11
type Profile struct {
    Name string
}
 
func new() Profile {
    return Profile{Name: "iswbm"}
}
 
func main() {
    fmt.Println(new().Name)
}

3. What are not addressable?

constant

?
1
2
3
4
5
6
7
import "fmt"
 
const VERSION  = "1.0"
 
func main() {
    fmt.Println(&VERSION)
}

character string

?
1
2
3
4
5
6
7
func getStr() string {
    return "iswbm"
}
func main() {
    fmt.Println(&getStr())
    // cannot take the address of getStr()
}

Function or method

?
1
2
3
4
5
6
7
func getStr() string {
    return "iswbm"
}
func main() {
    fmt.Println(&getStr)
    // cannot take the address of getStr
}

Basic type literal

Literal score:Basic type literal and compound literal.

The literal quantity of basic type is the text representation of a value, which should not and cannot be addressed.

?
1
2
3
4
5
6
7
8
func getInt() int {
    return 1024
}
 
func main() {
    fmt.Println(&getInt())
    // cannot take the address of getInt()
}

Elements in map

The dictionary is quite special. It can be deduced from two angles. Assuming that the elements of the dictionary are addressable, what problems will arise?

If the dictionary element does not exist, it returns a zero value, which is an immutable object. If it can be addressed, the problem will be great.

If the elements of the dictionary exist, consider in gomap The address of the element in the implementation changes, which means that the result of addressing is meaningless.

Based on these two points, the elements in the map are not addressable, which is in line with common sense.

?
1
2
3
4
5
6
7
8
func main() {
    p := map[string]string {
        "name": "iswbm",
    }
 
    fmt.Println(&p["name"])
    // cannot take the address of p["name"]
}

After understanding this, you should be able to understand why the following code is wrong~

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
 
import "fmt"
 
type Person struct {
    Name  string
    Email string
}
 
func main() {
    m := map[int]Person{
        1:Person{"Andy", "[email protected]"},
        2:Person{"Tiny", "[email protected]"},
        3:Person{"Jack", "[email protected]"},
    }
 
    //Compilation error: cannot assign to struct field m [1] Namein map
    m[1].Name = "Scrapup"

array literal

The array literal is not addressable. When you slice the array literal, you are actually looking for the address of the internal element. The following code will report an error

?
1
2
3
4
func main() {
    fmt.Println([3]int{1, 2, 3}[1:])
    // invalid operation [3]int literal[1:] (slice of unaddressable value)
}

This is the end of this article about understanding the addressable and non addressable contents in go. For more relevant addressable and non addressable contents in go, please search the previous articles of developeppaper or continue to browse the relevant articles below. I hope you will support developeppaper in the future!

Recommended Today

Generation of GUIDs in the database

GUID, namely Globally Unique Identifier (Globally Unique Identifier) ​​is also known as UUID (Universally Unique IDentifier). GUID is a digital identifier with a binary length of 128 bits generated by a specific algorithm to indicate the uniqueness of a product. GUIDs are primarily used in networks or systems with multiple nodes, multiple computers, to assign […]