GO言語でのインターネット


go言語に触れてから数ヶ月が経ちましたが、ほとんどのシステムパッケージはまだ熟練していませんが、goについても一定の理解があります.go言語は言語の面で非常に目立つところはありません.効率の面ではgo言語はc/c++に及ばず,移植性の面ではgo言語はjavaに及ばず,高同時性の面ではerlangもよくできる.だからgoは全能的な感じがして、いろいろな面で適当な取捨選択をしました.開発効率ではgoの方が速いです.
go言語ではinterfaceがポイントです.オブジェクト向け設計では,継承よりも組合せが優れている.go言語は継承を放棄し、組み合わせの面でよく表現されている.まずインターネットの使い方を見てみましょう.interfaceには2つの使い方があります.
1,空インタフェース,C/C++を使ったことのある人が空インタフェースの定義を見て最初に思いついたのがC/C++のvoid*です.
var Businesser interface{}
var IntData int = 100
var StringData string = "i love hxc" 

Businesser = IntData
var IntData2 int = Businesser.(int)

fmt.Println(Businesser)  // 100
fmt.Println(IntData2)   //100

Businesser = StringData
var StringData2 string = Businesser.(string)
fmt.Println(StringData2) // "i lobe hxc"
fmt.Println(Businesser) // "i love hxc"

上の使い方から見ると、空のインタフェースの使い方は確かにC/C++のvoid*と一致しているように見えます.しかし、C/C++のどこから来たvoid*タイプの変数(もちろん、プログラム設計の観点から、このような状況はできるだけ避けなければならない)では、元のタイプを判断することはできません.go言語では空のインタフェースに対してタイプによって断言したり、システムパッケージのreflectパケットを借りて空のインタフェースに割り当てられたデータ型を復元したりすることができます.
func InterfaceUsage(rhs interface{}) {
    switch val := rhs.(type) {
        case int:
            ...
         case string:
            ...
    }
}

空のインタフェースの説明から、空のインタフェースはオブジェクト向け言語のルートオブジェクトobjectに似ていることがわかります.しかし、go言語でinterfaceを使用する場合、注意が必要な問題があります.
var Businesser interface{}
var IntData int = 100
var StringData string = "i love hxc" 

Businesser = IntData
var IntData2 int = Businesser.(int)
IntData = 101

fmt.Println(Businesser)  // 100
fmt.Println(IntData2)   //100

Businesser = StringData
StringData = "hxc love me too"
var StringData2 string = Businesser.(string)
fmt.Println(StringData2) // "i lobe hxc"
fmt.Println(Businesser) // "i love hxc"

上記のコードの出力から、変数がインタフェースに割り当てられたときに、変数が空のインタフェースにコピーされることがわかります.これにより、私たちが見た変数の内容が変わり、空のインタフェースに保存されている変数の内容は変わりません.このような問題を回避する方法は、変数のアドレスを空のインタフェースに割り当てることであり、両者の内容の一致を保証し、大量のレプリケーション作業を回避することである.この態様の問題は非空インタフェースで一致している.
2、空でないインタフェース
go言語では継承を明示的にサポートしていない.しかし継承を実現する方法も提供され,実現も直感的ではない.go言語では、空でないインタフェースを使用することをお勧めします.空でないインタフェースの使用方法は次のとおりです.
type Personer interface {
    Walk()
    ChangeName(string)
}

type GoodPerson struct {
    name string
}

func NewGoodPerson(name string) *GoodPerson {
    return &GoodPerson{name}
}

func (this *GoodPerson)Walk() {
    fmt.Println(this.name, " walking")
}

func (this *GoodPerson)ChangeName(name string) {
    this.name = name
}

func (this *GoodPerson)Fly() {
    fmt.Println("man can't fly")
}

func main() {
    var Person Personer = NewGoodPerson("hxc")
    var Person2 interface{} = Person
    
    Person.Walk() // "hxc walking"
    Person.ChangeName("wzm")
    Person.Walk() // "wzm walking"
    // Person.Fly() // error Personer have no field or mothed name Fly
   // Person2.Walk() // error
   //Person = 1 //error
}

1つのデータ型がインタフェースの方法を実装すると、そのデータ型は空でないインタフェースに値を割り当てることができる.データ型が空でないインタフェースを実装する方法がない場合、空でないインタフェースに値を割り当てることはできません.空のインタフェースは同じように割り当てられたインタフェースであり、その下位層はコピーされるので、データ型でインタフェースを実現する方法はポインタを伝達するのがよい.これにより、非空インタフェースが呼び出されると、その非空インタフェース変数に割り当てられた内容を変更することができるからである.
go言語では、1つのデータ型は、どのインタフェースが実装されたかを他の言語のように明示的に説明する必要はありません.したがって、1つのデータ型は、複数のインタフェースを実現することができる.go言語にはc++のような構造関数がないため、習慣的にgo言語は1つの工場を通じて特定のデータ変数を生成する.