指针
Pointers are complex data types that store the memory address of value. Simply put, if we have a value stored in the memory address as 100 and a pointer to that value, the pointer value will be 100. The default value for a pointer is nil. Nil pointer does not point to any value.
指针是存储值的内存地址的复杂数据类型。简单地说,如果在内存地址中存储了一个值100和一个指向该值的指针,那么指针的值就是100。指针的默认值是nil。Nil指针不指向任何值。
To declare a pointer, we must add *(asterisk)
before type. This will declare an integer pointer:
要声明指针,必须在type前面加上“*(星号)”。声明一个整型指针:
var pi *int
Go has two pointer operators:
- Operator
&(ampersand)
will get the address of the variable. We use this operator to initialize or assign a value for a pointer (i is an integer variable):pi := &i
. - Operator
*(asterisk)
will get us access to the pointed value. We can use it for the following operators:- Read value hrough pointer:
i := *pi
- Set value through pointer:
*pi = 33
- Read value hrough pointer:
Go有两个指针操作符:
- 操作符“&(&)”将获得变量的地址。使用该操作符为指针(i为整型变量)初始化或赋值:
pi:= &i
。 - 操作符“*(星号)”将使我们访问指向的值。可以将其用于以下操作符:
- 通过指针读取值:
i:= *pi
- 通过指针设置值:
*pi = 33
- 通过指针读取值:
In the following example, we will use a pointer to change the value of the integer variable (value 27 will be displayed on the standard output at the end):
在下面的例子中,我们将使用一个指针来改变整型变量的值(值27将在最后的标准输出中显示):
func main(){var i int = 18var pi *intpi = &i*pi = 27fmt.Println(i)
}
Some programming languages support pointer arithmetic. Pointer arithmetic allows us to perform simple arithmetic operations such as increment, decrement, addition, and subtraction. These operations will not change pointed values, but they will change the pointer value. Let’s assume that the pointer points to memory address 100. If we perform an increment arithmetic operation on a pointer, it will now point to address 101. Designers of the Go programming language wanted to keep things as simple as possible. So, they decided through unsafe package. As the name suggests, usage of this package is not recommended and should be avoided(if possible).
一些编程语言支持指针运算。指针算术允许我们执行简单的算术操作,如自增、自减、加法和减法。这些操作不会改变指针指向的值,但会改变指针地址的值。让我们假设指针指向内存地址100。如果对指针执行自增算术运算,它现在将指向地址101。Go编程语言的设计者希望尽可能地保持简单。所以,他们决定通过不安全的包装。顾名思义,不建议使用这个包,应该避免使用(如果可能的话)。
结构体
Struct (shortenedof structure) is a complex data type that can be defined as a collection of fields. Fields can be of different types. We use type and struct keywords to declare struct, with the name in between them. Fields are declared of betweencurly brackets in classical name-type declaration style. Here is an example of struct person which has two fields, name and age.
结构是一种复杂的数据类型,可以定义为字段的集合。字段可以是不同的类型。我们使用type和struct关键字来声明struct,在它们之间加上名称。以经典的名称类型声明风格在括号之间声明字段。下面是一个结构体person的例子,它有两个字段:name和age。
type person struct {name stringage int
}
We can access struct fields with the .(dot)
operator. We can access the field in order to set, update, or read its value. This example will update the age of the created person.
我们可以使用.(点)
操作符访问结构体字段。我们可以访问字段来设置、更新或读取它的值。这个示例将更新所创建人员的年龄。
p := person{name: "Mara",age: 27,
}
p.age = 33
We can declare a pointer to a struct and use the pointer to access fields. If we follow all pointer rules described in the previous section, the statement that will update the value of the field age should be (pp is pointer to person):
可以声明指向结构体的指针,并使用该指针访问字段。如果我们遵循上一节中描述的所有指针规则,将更新字段age值的语句应该是(pp是指向person的指针):
(*pp).age = 35
The previous statement is a little bit complex and unreadable. So, in Go, the design statement is simplified.
前面的语句有点复杂,难以读懂。因此,在Go中,设计语句被简化了。
pp.age = 33
In the example where we created person, we provided values for all fields. In such situations, we can omit the field name from the definition. Also, we can provide values only for certain fields(in this case, we cannot omit field names) or omit values for all fields. Default values will be assigned to the omitted fields.
在我们创建person的示例中,我们为所有字段提供了值。在这种情况下,我们可以从定义中省略字段名。此外,我们可以仅为某些字段提供值(在这种情况下,我们不能省略字段名)或省略所有字段的值。默认值将分配给省略的字段。
Here are a couple of examples of how we can define struct variable:
下面是几个如何定义struct变量的例子:
p1 := person{"Mara", 33}
p2 := person{name:"Mara"}
p3 := person{}
One important thing, export rules are also applied to struct fields. Even if struct itself is exported, if the field is not exported, other packages will not be able to access it.
重要的一点是,导出规则也适用于结构字段。即使struct本身被导出,如果字段没有被导出,其他包也不能访问它。