2013-05-20 27 views
5

繞過訪問權限,比方說,我有我的項目以下層次:圍棋編程 - 使用指針

fragment/fragment.go 
main.go 

而在fragment.go我有下面的代碼,其中一個getter和沒有setter:

package fragment 

type Fragment struct { 
    number int64 // private variable - lower case 
} 

func (f *Fragment) GetNumber() *int64 { 
    return &f.number 
} 

而在main.go我創建了一個Fragment並試圖改變Fragment.number沒有二傳手:

package main 

import (
    "fmt" 
    "myproject/fragment" 
) 

func main() { 
    f := new(fragment.Fragment) 

    fmt.Println(*f.GetNumber()) // prints 0 

    //f.number = 8 // error - number is private 

    p := f.GetNumber() 
    *p = 4      // works. Now f.number is 4 
    fmt.Println(*f.GetNumber()) // prints 4 
} 

所以通過使用指針,我改變了fragment包之外的私有變量。我明白在例如C中,指針有助於避免複製大型結構/數組,並且它們應該使您能夠更改指向的任何內容。但我不太明白他們應該如何處理私有變量。

所以我的問題是:

  1. 不宜私有變量留民營,不管他們是如何訪問?
  2. 這與其他語言如C++/Java相比如何?是否也有這種情況,可以使用類之外的指針來更改私有變量?

我的背景:我知道一點C/C++,很流利的Python和新的Go。我把編程作爲一種愛好學習,所以不瞭解幕後發生的技術事情。

+2

指針是對內存中某個地方的引用。如果你返回一個指向「私有」變量的指針,它仍然指向那個變量;調用者仍然可以更改指針。如果您想強制執行「不變更」限制,請考慮返回對象本身,而不是僅複製副本。 – fuz

回答

7

你是不繞過任何訪問權限。如果你從任何進口包裝中獲得* T,那麼你可以總是 mutate * T,即。整個指針,就像在一個任務中一樣。導入的包設計器控制你可以從包中獲得什麼,所以訪問控制不是你的。

對上述內容的限制是針對結構化類型(結構體),其中前面仍然存在,但對特定字段的訪問控制的更細粒度由字段的名稱大小寫控制,即使通過指向整個結構。字段名稱必須是大寫字母才能在其包裝外部可見。

Wrt C++:我相信你可以用幾十個C++指針類型中的一個來實現。不知道哪一個,但。

Wrt Java:不,Java沒有指針。與Go(C,C++,...)中的指針沒有什麼可比性。

+2

這是完全正確的。訪問不是關於變異 - 而是關於可見性。你不能*看到package外的* frag.number - 訪問它是非法的;然而,如果fragment給你一個碰巧指向frag.number的指針,那麼你可以自由修改它。這在C++中是完全正確的。 – weberc2

+0

這也正是它在Python中的工作原理,儘管[在Python中]默認情況下,一切都是「指針」。 – weberc2

+0

有趣:)謝謝! – user31208