【GO for java programmers】面向Java開發人員的GO編程3

來源:互聯網
上載者:User
文章目錄
  • 方法
  • 介面
  • 匿名域
  • 類型斷言
面向Java開發人員的GO編程

英文原文在此www.nada.kth.se/~snilsson/go_for_java_programmers

譯文同步至www.waylau.com

http://bbs.gocn.im/thread-86-1-1.html

=======================接上文========================.

Slices(切片)

slice是概念上一個結構包含三個域:一個數組的指標、長度和容量。切片支援[]操作符來訪問底層數組的元素。內建的len函數返回的切片長度。內建的的cap函數返回切片的能力。

給定一個數組,或另一個切片,通過a[i:j]來建立一個新的切片。這個新建立的切片指向a,從索引i開始,並結束索引j之前。它的長度是j - i。如果i 被省略,切片從0開始。如果j 被省略,切片在len(a)結束。新切片跟a一樣指向相同的數組。即,改變後組成的新的切片的元素在a都能見到。新切片的容量就是簡單的a減去i。數組的容量就是數組的長度。

var s []intvar a [10]ints = a[:]  // short for s = a[0:len(a)]

如果你建立一個實值型別為[100]byte(100個位元組,也許是一個緩衝區的數組),你想不複製它,而將它傳遞給函數,那麼函數的參數宣告類型[]byte,並傳入數組的切片。切片也可以用make的函數建立(如下文所述)。

切片組合採用內建的append函數,Java的ArrayList提供相同的功能。

s0 := []int{1, 2}s1 := append(s0, 3)      // append a single elements2 := append(s1, 4, 5)   // append multiple elementss3 := append(s2, s0...)  // append a slice

切片文法,也可以使用在字串上。它返回一個新字串,其值是原始的字串的子串

make函數

Map and channel values must be allocated using the built-in function make. For example, calling map和channel值必須使用內建的函數make。例如,調用

make(map[string]int)

map[string]int返回一個新分配的實值型別。相對於newmake 返回的是實際的對象,而不是一個地址。這是一致的事實,map和channel是參考型別。

對於map,make函數將容量作為一個可選的第二個參數的提示。對於channel,有一個可選的第二個參數來設定channel的緩衝能力,預設為0(無緩衝)。

make函數也可以用來分配一個切片。在這種情況下,它分配記憶體給基本數組並返回一個引用他的切片。該切片中的元素數是一個必要參數。第二個可選的參數是切片的容量。

m := make([]int, 10, 20)  // Same as new([20]int)[:10]
方法和介面方法

方法看起來像一個普通的函數定義,但它有一個receiver(接收者)。receiver是類似Java執行個體方法中的this引用。

type MyType struct { i int }func (p *MyType) Get() int {    return p.i}var pm = new(MyType)var n = pm.Get()

這聲明了一個方法GetMyType關聯的。receiver被命名為p 在函數體內。

命名的類型來定義方法。如果您轉換不同類型的值,新的值將有新的類型,而不是那些舊的類型。

你可以定義一個內建類型的方法,用新的命名型別宣告。新的類型和內建的類型是不同的。

type MyInt intfunc (p MyInt) Get() int {    return int(p)  // The conversion is required.}func f(i int) {}var v MyIntv = v * v          // The operators of the underlying type still apply.f(int(v))          // int(v) has no defined methods.f(v)               // INVALID
介面

Go介面類似於Java介面,但可被視為一個實現該介面提供任何類型的在Go介面命名的方法。明確的聲明是不必要的。

介面像這樣:

type MyInterface interface {    Get() int    Set(i int)}

自從 MyType 已經有了Get 方法, 我們可以讓 MyType滿足介面通過添加

func (p *MyType) Set(i int) {    p.i = i}

現在任何只要將MyInterface當做參數就可以接收類型是*MyType的變數

func GetAndSet(x MyInterface) {}func f1() {    var p MyType    GetAndSet(&p)}

在Java術語,給*MyType 定義 SetGet 使*MyType自動實現了MyInterface介面。這種類型型可滿足多個介面。這是一種形式的鴨子類型。

“當看到一隻鳥走起來像鴨子、遊泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。”

James Whitcomb Riley

匿名域

匿名域可以用於實現很像一個Java子類的東西。

type MySubType struct {    MyType    j int}func (p *MySubType) Get() int {    p.j++    return p.MyType.Get()}

MySubType有效實現的像是MyType的子類型.

func f2() {    var p MySubType    GetAndSet(&p)}

Set方法是繼承自MyType的,因為關聯了匿名域的方法的變為了封閉類型的方法。在這種情況下,因為
MySubType
有一個匿名與域 MyType類型,所以為 MyTypee的方法也成為MySubType的方法。Get方法被重寫,Set方法被繼承。

這是與Java中的子類不完全相同。當一個匿名域的方法被調用時,它的 receiver就是這個匿名域,而不是周圍的結構體。換句話說,匿名域上的方法的不會動態調度。當你想要實現相當於Java的動態方法尋找,請使用介面。

func f3() {    var v MyInterface    v = new(MyType)    v.Get()  // Call the Get method for *MyType.    v = new(MySubType)    v.Get()  // Call the Get method for *MySubType.}
類型斷言

使用一個類型斷言可以使具有一個介面類型的變數轉換成具有不同的介面類型。這是在運行時動態執行。與Java不同,並不需要任何聲明兩個介面之間的關係。

type Printer interface {    Print()}func f4(x MyInterface) {    x.(Printer).Print()  // type assertion to Printer}

轉換為Printer 完全是動態。只要x(x中儲存的值的實際類型)的 動態類型 定義了一個Print方法。

===================未完待續.......==========

===================轉載註明出處=============

2013-1-4

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.