#他の人の Go コードを見ると、コード内でポインターを使用している人もいれば、使用していない人もいることに気づきます。(推奨学習:go)
Person という構造体タイプがあり、一部のメソッドがパラメーターとして func methodA (*person Person) を使用していることが判明したとします。 use func *( person Person) methodA() は、構造体独自のメソッドとして使用されます。つまり、person 構造体は、ポインターを使用して、methodA を直接呼び出すことができます。
または、マップ構造内の var personMap map[string]*person の使用法を確認できます。
Java から golang に移行すると、理解するのが簡単ではないかもしれません。 Javaの世界にはポインタがないので直接渡して使えますが、golangとなると色々と注意が必要です。
では、いつ使用する必要がありますか?なぜ一部の場所では必要なのでしょうか?
ポインタを使用しない場合、場合によっては構造体に値を割り当てることができません。コードを見てみましょう。このコードはポインタを使用せず、最初に束を定義しています。テスト用のオブジェクトの数
type Person struct { //person结构体,包含年龄,名称,车 age int name string car Car } type Car struct { //person名下的车 name string //车的名字 } var personMap map[string]Person //一个存放person的map func setName(person Person, name string) { //给参数person设置名字 person.name = name } func (person Person) setName(name string) { //设置名字 person.name = name } func printName(person Person){ //打印person的名字 fmt.Println(person.name) } func (person Person)printName(){ //结构体person自己支持打印名字 fmt.Println(person.name) }
次に、main メソッドを記述します。出力された結果をコード内でコメントします。多くの場合、代入が失敗することがわかります。
func main() { person := Person{} fmt.Println(person) //{0 {}} person.age = 12 person.name = "小明" person.car = Car{"宝马"} fmt.Println(person) //{12 小明 {宝马}},正常赋值给person变量,因为这是在方法里面的变量 setName(person, "小红") fmt.Println(person) //{12 小明 {宝马}},小红赋值失败,传递给setName方法的person没有赋值成功 person.setName("小红") fmt.Println(person) //{12 小明 {宝马}},person自己setName,还是失败 personMap = make(map[string]Person) personMap["test"] = person person = personMap["test"] person.name = "小红" fmt.Println(person) //{12 小红 {宝马}},从map中取出person,给小红赋值成功 for _, value := range personMap { //遍历map fmt.Println(value)//{12 小明 {宝马}},打印的还是小明,而不是小红,说明上面personMap["test"]对象赋值失败 } }
次に、ポインターを使用するように変換します
type Person struct { age int name string car Car } type Car struct { name string } var personMap map[string]*Person func setName(person *Person, name string) { person.name = name } func (person *Person) setName(name string) { person.name = name } func printName(person Person){ fmt.Println(person.name) } func (person Person)printName(){ fmt.Println(person.name) }
main メソッドを変更し、& アドレス文字を使用します
func main() { person := Person{} fmt.Println(person) //{0 {}} person.age = 12 person.name = "小明" person.car = Car{"宝马"} fmt.Println(person) //打印{12 小明 {宝马}} setName(&person, "小红") fmt.Println(person) //{12 小红 {宝马}}, 成功赋值! person.setName("小黑") fmt.Println(person) //{12 小黑 {宝马}}, 成功赋值! personMap = make(map[string]*Person) personMap["test"] = &person person = *personMap["test"] person.name = "小兰" fmt.Println(person) //{12 小兰 {宝马}},成功赋值! for _, value := range personMap { fmt.Println(value) //&{12 小兰 {宝马}},读取的也是正确的小兰 } }
結論として、構造体の変数の内容を変更する必要がある場合、メソッドによって渡される構造体の変数パラメーターはポインターを使用する必要がありますつまり、構造体のアドレスを変更する必要がある場合マップ内のアーキテクチャの変数を変更するには、マップの値として構造体のアドレスを使用する必要もあります。
構造体変数を読み取るだけの場合は、 pointer
#*type ここの type 変数にはアドレスが格納されます。これは明確にする必要があります。アドレスを取得するには &type を使用する必要があります。以上がgolangではポインタが使えないのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。