ポインタ
ゴー言語関数のパラメータは、値をコピーするために渡された私たちはとき、あなたは、変数を変更したいとき、私たちができる変数のアドレスを指していることをポインタ変数を作成します。
ポインタでのC / C ++とは異なり、囲碁言語のポインタを移動させることができず、操作は安全なポインタです。
:ゴーあなたが3つのコンセプトを知っておく必要があり、ポインタの言語を理解したいポインタアドレス、ポインタ型、およびポインタ値を。
そして、ポインタ型ポインタアドレス
:ゴー言語ポインタ操作は非常に簡単で、たった2つの記号を覚えておくことが必要である
&
(アドレス)、及び*
(アドレス値)。実行時に、各変数がアドレスを有し、アドレスがメモリ内の可変位置を表します。ゴー言語は変数の変数の前にアンパサンドを使用する操作「のアドレスを取ります」。
ポインタ変数の構文を取り、次のとおりです。
ptr := &v // v的类型为T
どこで:
v:代表被取地址的变量,类型为T
ptr:用于接收地址的变量,ptr的类型就为*T,称做T的指针类型。*代表指针。
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
}
ポインタ値
そしてアドレス値演算子&演算子は、
*
相補的なオペレータのペアであり、&
フェッチアドレスを、*
アドレスが抽出されたアドレス値によって指されます。
次のように変数、特性およびアドレスポインタの関係は、ポインタ変数は、アドレスを取って、値です。
1.アドレス変数をフェッチ(&)の動作は、この変数ポインタ変数を得ることができます。
2.ポインタ変数の値がポインタのアドレスです。
3.ポインタ変数(*)操作の値は、元の変数の値は、ポインタ変数のポイントを得ることができます。
- 変数が定義されているポインタのいずれにも割り当てられていない場合、その値はゼロであります
ポインタ変数の初期化
func main() {
var a *int
*a = 100
fmt.Println(*a)
var b map[string]int
b["测试"] = 100
fmt.Println(b)
}
// panic: runtime error: invalid memory address or nil pointer dereference
//[signal 0xc0000005 code=0x1 addr=0x0 pc=0x49a7ca]
上記のコードの実装は、なぜ、パニックにつながるのだろうか?
- 囲碁の言語では使用時には、参照型の変数のために、我々はそれを宣言しなければならないだけでなく、そのためのメモリ空間を割り当てるために、そうでない場合、我々は店の価値に方法がありません。
- 用として、彼らは、それが宣言された良いのデフォルト割り当てられたメモリ空間を持っているため、ステートメントの種類の値は、あなたは、メモリ空間を割り当てる必要はありません。
移動して、新しい言語を作る2は、組み込み関数され、主にメモリを割り当てるために使用されます
func new(Type) *Type
func make(t Type, size ...IntegerType) Type
1.両方がメモリ割り当てのために使用されます。
2. のみスライス、マップ、チャネル、または基準自体の三種類の復帰初期化するためのメーク ;
戻り値ゼロ値に対応する前記メモリ割当ての新しいタイプの、およびメモリタイプは、ポインタ型でありますポインタ。
地図
ゴー言語マップは、使用前に初期化する必要があり、参照型で、あるの障害キー値ベースのデータ構造
func main() {
scoreMap := make(map[string]int, 8)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
fmt.Println(scoreMap)
fmt.Println(scoreMap["小明"])
fmt.Printf("type of a:%T\n", scoreMap)
}
範囲のトラバースマップに使用するゴー言語
func main() {
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["王五"] = 60
for k, v := range scoreMap {
fmt.Println(k, v)
}
}
トラバーサル順序指定されたマップ
func main() {
rand.Seed(time.Now().UnixNano()) //初始化随机数种子
var scoreMap = make(map[string]int, 200)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
value := rand.Intn(100) //生成0~99的随机整数
scoreMap[key] = value
}
//取出map中的所有key存入切片keys
var keys = make([]string, 0, 200)
for key := range scoreMap {
keys = append(keys, key)
}
//对切片进行排序
sort.Strings(keys)
//按照排序后的key遍历map
for _, key := range keys {
fmt.Println(key, scoreMap[key])
}
}
マップ要素のタイプは、スライスしました
func main() {
var mapSlice = make([]map[string]string, 3)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
fmt.Println("after init")
// 对切片中的map元素进行初始化
mapSlice[0] = make(map[string]string, 10)
mapSlice[0]["name"] = "王五"
mapSlice[0]["password"] = "123456"
mapSlice[0]["address"] = "红旗大街"
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
}
スライスタイプ値マップ
func main() {
var sliceMap = make(map[string][]string, 3)
fmt.Println(sliceMap)
fmt.Println("after init")
key := "中国"
value, ok := sliceMap[key]
if !ok {
value = make([]string, 0, 2)
}
value = append(value, "北京", "上海")
sliceMap[key] = value
fmt.Println(sliceMap)
}
構造
ゴー言語は継承し、他のオブジェクト指向の概念の「クラス」をサポートしていません「クラス」の概念がありません。
言語を経る構造に埋め込まれたと一緒にインターフェイスオブジェクト指向より高い拡張性と柔軟性をより。
型定義と型の別名との違い
タイプエイリアスタイプ定義面の一方のみ等号の差
//类型定义
type NewInt int
//类型别名
type MyInt = int
func main() {
var a NewInt
var b MyInt
fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
fmt.Printf("type of b:%T\n", b) //type of b:int
}
構造体
構造体でのオブジェクト指向言語に行きます
アドレス構造を取ります
type student struct {
name string
age int
}
func main() {
m := make(map[string]*student)
stus := []student{
{name: "pprof.cn", age: 18},
{name: "测试", age: 23},
{name: "博客", age: 28},
}
for _, stu := range stus {
m[stu.name] = &stu
}
for k, v := range m {
fmt.Println(k, "=>", v.name)
}
}
コンストラクタ構造は、自分自身を達成することはできません
言語のゴー構造には、コンストラクタ、私たち自身の実現を持っていません。例えば、人のコンストラクタの実現に以下のコード。構造が複雑である場合、パフォーマンス・オーバーヘッドのコピー値は、コンストラクタは、構造型へのポインタを返すように、比較的大きくなり、ので、構造体型の値であります
func newPerson(name, city string, age int8) *person {
return &person{
name: name,
city: city,
age: age,
}
}
コンストラクタを呼び出します
p9 := newPerson("pprof.cn", "测试", 90)
fmt.Printf("%#v\n", p9)
受信方式と受信者
Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。
方法的定义格式如下:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
函数体
}
其中,
1.接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名的第一个小写字母,而不是self、this之类的命名。例 如,Person类型的接收者变量应该命名为 p,Connector类型的接收者变量应该命名为c等。
2.接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。
3.方法名、参数列表、返回参数:具体格式与函数定义相同。
举个例子:
//Person 结构体
type Person struct {
name string
age int8
}
//NewPerson 构造函数
func NewPerson(name string, age int8) *Person {
return &Person{
name: name,
age: age,
}
}
//Dream Person做梦的方法
func (p Person) Dream() {
fmt.Printf("%s的梦想是学好Go语言!\n", p.name)
}
func main() {
p1 := NewPerson("测试", 25)
p1.Dream()
}
方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。
结构体的“继承”
Go语言中使用结构体也可以实现其他编程语言中面向对象的继承。
//Animal 动物
type Animal struct {
name string
}
func (a *Animal) move() {
fmt.Printf("%s会动!\n", a.name)
}
//Dog 狗
type Dog struct {
Feet int8
*Animal //通过嵌套匿名结构体实现继承
}
func (d *Dog) wang() {
fmt.Printf("%s会汪汪汪~\n", d.name)
}
func main() {
d1 := &Dog{
Feet: 4,
Animal: &Animal{ //注意嵌套的是结构体指针
name: "乐乐",
},
}
d1.wang() //乐乐会汪汪汪~
d1.move() //乐乐会动!
}
结构体字段的可见性
结构体中字段大写开头表示可公开访问,小写表示私有(仅在定义当前结构体的包中可访问)。
参考链接:
http://www.topgoer.com/go%E5%9F%BA%E7%A1%80/%E7%BB%93%E6%9E%84%E4%BD%93.html