這個是根據你值的內容來定的啊,看代碼
創新互聯公司專業為企業提供綠園網站建設、綠園做網站、綠園網站設計、綠園網站制作等企業網站建設、網頁設計與制作、綠園企業網站模板建站服務,10余年綠園做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
type?User?struct?{
Name?string
}
//例1(返回指針)
func?test1()*User{
return?new(User)?
}
//例2(返回指針)
func?test2()*User{
return?User{}
}
//例3(返回值)
func?test3()User{
return?User{}
}
明白沒有?
golang方法(method)返回值提取結構體(struct)取不到地址的原因是,①返回值并沒有保存到變量中,返回值本身只是臨時保存在程序運行的堆棧的某個不確定位置,不能取地址;②實參取地址用的操作符是是,而形參聲明變量類型為指針,需要地址值用的才是*;③聲明形參為指針的參數的實參只能為地址值。
故先把修改后的代碼列出,修改要點是把“*NewPerson1().Speak()”改為“var b=NewPerson1();(b).Speak()”,同時把“NewPerson2().Speak()”改成“var a=NewPerson2();(a).Speak()”,代碼列出如下:
package main;
import "fmt";
type PersonA struct{
name string
}
func (p *PersonA) Speak () {
fmt.Println ( "person speak" ,p.name)
}
func (p PersonA) Walk ( ){
fmt . Println ( "person walk",p.name)}
func NewPerson1()(p PersonA){
return PersonA{"new Person1"}}
func NewPerson2()(p PersonA){
return PersonA{"new Person2"}}
func main () {
var a=NewPerson2 (); (a).Speak ();?
a .Walk ();
fmt. Println ("--------------------")?;
var b=NewPerson1 ();(b).Speak ();
b.Walk ()}
go代碼調試效果
關于指針變量的使用這一點go語言和其他有指針的程序語言如c語言是一樣的,從來只有返回值為地址/指針,而從沒有在賦值前給返回值取地址這種運算,類似的錯誤晚點再整理。
不一樣的是,go語言更簡單go語言函數可以使用結構體或者結構體的指針(pointer)以傳遞結構體參數,而且和c語言不一樣的是,go語言沒有區分結構體指針和結構體訪問成員的運算符,go語言只有“.”適用于兩種情況,而沒有c語言為結構體指針專門準備的“-”運算符。
可以使用結構體指針,作為結構體的方法的參數以指代自身嗎,
go語言中的指針和地址值,在使用上常常具有迷惑性,主要是其特殊的*、符號的使用,可能會讓你摸不透,本文希望能講清楚go語言的指針(pointer)和值(value)。
這里先簡單的對指針和地址值概念做一個定義:
這是因為go方法傳遞參數的方式導致的,go方法函數傳遞參數傳遞的是一個拷貝,看看下面的程序會輸出什么?
答案是8,而不是9,因為AddAge函數修改的是學生的一個備份,而不是原始的學生對象
如果你想正確的給學生年齡增加的話,函數傳遞的需要是這個值的指針,如下所示:
需要注意的是,這里我們的指針傳遞的仍然是一個拷貝,比如,如果你將s賦值給另外一個指針地址,不會影響原有的指針,這點可以自行實踐下。
那在使用go語言開發的時候,何時該用指針何時改用地址值呢?比如考慮以下場景:
簡單原則: 當你不確定該使用哪種的時候,優先使用指針
如果考慮在數組、切片、map等復合對象中使用指針和值,比如:
很多開發者會認為b會更高效,但是被傳遞的都是一個切片的拷貝,切片本身就是一個引用,所以這里被傳遞的其實沒有什么區別。
對于指針和地址值的使用,大家需要牢記的一點就是go數據傳遞的不可變性,活學活用此特點,在無狀態函數中此特性非常有用。