構造および方法

package main

import "fmt"

// 示例1。
// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
    kingdom string // 界。
    phylum  string // 门。
    class   string // 纲。
    order   string // 目。
    family  string // 科。
    genus   string // 属。
    species string // 种。
}

//这里绑定,这个String方法不需要任何参数声明,但需要有一个string类型的结果声明。我在调用fmt.Printf函数时,使用占位符%s和category值本身就可以打印出后者的字符串表示形式,而无需显式地调用它的String方法。
func (ac AnimalCategory) String() string {
    return fmt.Sprintf("%s%s%s%s%s%s%s",
        ac.kingdom, ac.phylum, ac.class, ac.order,
        ac.family, ac.genus, ac.species)
}

// 示例2。
type Animal struct {
    scientificName string // 学名。
    AnimalCategory        // 动物基本分类。这是一个嵌入字段
}

// 该方法会"屏蔽"掉嵌入字段中的同名方法。
// func (a Animal) String() string {
//  return fmt.Sprintf("%s (category: %s)", //Sprintf输出格式化的字符串
//      a.scientificName, a.AnimalCategory)
// }

// 示例3。
type Cat struct {
    name string
    Animal
}

// 该方法会"屏蔽"掉嵌入字段中的同名方法。
// func (cat Cat) String() string {
//  return fmt.Sprintf("%s (category: %s, name: %q)",
//      cat.scientificName, cat.Animal.AnimalCategory, cat.name)
// }

func main() {
    // 示例1。species字段指定了字符串值"cat",fmt.Printf函数会自己去寻找它。此时的打印内容会是The animal category: cat。
    category := AnimalCategory{species: "cat"}
    fmt.Printf("The animal category: %s\n", category)

    // 示例2。

    animal := Animal{
        scientificName: "American Shorthair",
        AnimalCategory: category,
    }
    fmt.Printf("The animal: %s\n", animal)

    // 示例3。
    cat := Cat{
        name:   "little pig",
        Animal: animal,
    }
    fmt.Printf("The cat: %s\n", cat)
}
go run demo29.go 
The animal category: cat
The animal: cat
The cat: cat

なぜここ3匹の猫はそれを印刷しますか?

なぜなら:猫の文字列()メソッド:FUNC(猫猫)文字列()文字列、および動物の方法:FUNC(動物)文字列()文字列は、スクリプトの実行時間をコメント化されたときに実施例2及び実施例3 fmt.Printf()メソッドを呼び出して、あなただけの7分野を印刷するには、FUNC(交流AnimalCategory)文字列()は、文字列メソッドを使用することができます。コメントがなければ、文字列の後ろの方法は、以前の文字列メソッドを上書きした結果の変更を表示します。

package main

import "fmt"

// 示例1。
// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
    kingdom string // 界。
    phylum  string // 门。
    class   string // 纲。
    order   string // 目。
    family  string // 科。
    genus   string // 属。
    species string // 种。
}

//这里绑定,这个String方法不需要任何参数声明,但需要有一个string类型的结果声明。我在调用fmt.Printf函数时,使用占位符%s和category值本身就可以打印出后者的字符串表示形式,而无需显式地调用它的String方法。
func (ac AnimalCategory) String() string {
    return fmt.Sprintf("%s%s%s%s%s%s%s",
        ac.kingdom, ac.phylum, ac.class, ac.order,
        ac.family, ac.genus, ac.species)
}

// 示例2。
type Animal struct {
    scientificName string // 学名。
    AnimalCategory        // 动物基本分类。这是一个嵌入字段
}

// 该方法会"屏蔽"掉嵌入字段中的同名方法。
func (a Animal) String() string {
    return fmt.Sprintf("%s (category: %s)", //Sprintf输出格式化的字符串
        a.scientificName, a.AnimalCategory)
}

// 示例3。
type Cat struct {
    name string
    Animal
}

// 该方法会"屏蔽"掉嵌入字段中的同名方法。
func (cat Cat) String() string {
    return fmt.Sprintf("%s (category: %s, name: %q)",
        cat.scientificName, cat.Animal.AnimalCategory, cat.name)
}

func main() {
    // 示例1。species字段指定了字符串值"cat",fmt.Printf函数会自己去寻找它。此时的打印内容会是The animal category: cat。
    category := AnimalCategory{species: "cat"}
    fmt.Printf("The animal category: %s\n", category)

    // 示例2。
    //使用fmt.Printf函数和%s占位符试图打印animal的字符串表示形式,相当于调用animal的String方法。
    //虽然我们还没有为Animal类型编写String方法,但这样做是没问题的。
    //因为在这里,嵌入字段AnimalCategory的String方法会被当做animal的方法调用。
    //那如果我也为Animal类型编写一个String方法呢?这里会调用哪一个呢?
    //animal的String方法会被调用。这时,我们说,嵌入字段AnimalCategory的String方法被“屏蔽”了。注意,只要名称相同,无论这两个方法的签名是否一致,被嵌入类型的方法都会“屏蔽”掉嵌入字段的同名方法。
    animal := Animal{
        scientificName: "American Shorthair",
        AnimalCategory: category,
    }
    fmt.Printf("The animal: %s\n", animal)

    // 示例3。
    cat := Cat{
        name:   "little pig",
        Animal: animal,
    }
    fmt.Printf("The cat: %s\n", cat)
}
daixuandeMacBook-Pro:q0 daixuan$ go run demo29.go 
The animal category: cat
The animal: American Shorthair (category: cat)
The cat: American Shorthair (category: cat, name: "little pig")

データ・タイプに関連付けられたすべての方法は、一緒になって、このタイプのメソッドのセットを構成しています。同じ名前の収集方法と同じように表示することはできません。彼らは任意のフィールド名にそのその後、型名、構造の種類に属している場合や、重複することもできません。

我々は、フィールド構造の種類を置くことができ、その特性の一つ、又はデータと考えられ、その後に上記容量やデータ操作方法の拡張として、それに取り付けられています。特性および能力(又はデータ及び操作)一緒にパッケージ化、オブジェクト指向プログラミング

私は動物と呼ばれる構造の種類を、宣言しました。これは、2つのフィールドがあります。一つは、動物の学名を表す、フィールドscientificNameの文字列型です。そして、フィールド宣言のみAnimalCategoryの別のタイプの構造ということ、それは私が名前の前に書いたものです。それは何を意味するのでしょうか?

質問は次のとおりです。動物の種類が表すAnimalCategoryフィールド宣言?

動物のフィールドAnimalCategoryのタイプに代わって声明埋め込みフィールドフィールド名のない唯一のフィールドのフィールド内のタイプ名は、それがフィールドに埋め込まれている場合のGo言語仕様は、フィールドも匿名で呼び出すことができます。私たちは、「」に続いて、この変数の名前を入力し、[フィールドへの参照の組み込みフィールド型が続くことができます。言い換えれば、型の名前の両方が埋め込まれたフィールドのタイプです。

フィールドの構造に組み込まれた参考文献といえば、動物の種類は、メソッドと呼ばれるカテゴリーは、それがそう書かれています:

func (a Animal) Category() string {
return a.AnimalCategory.String()}

レシーバタイプのアプローチは、受信者の名前は、そのカテゴリーの動物です。この方法では、I埋め込みフィールドの発現による選択にa.AnimalCategory、その後は、フィールドの文字列メソッドを選択し、それを呼び出します。

なお、変数を表す識別子の右プラス「」、フィールド名または式は、フィールドまたは変数の選択を示すために使用されるメソッド名選択式と呼ばれていると共に方法。

おすすめ

転載: blog.51cto.com/daixuan/2458688