ホームページ  >  記事  >  バックエンド開発  >  golang のタイプとはどういう意味ですか?

golang のタイプとはどういう意味ですか?

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼オリジナル
2019-12-10 10:26:043692ブラウズ

golang のタイプとはどういう意味ですか?

type は Go 文法で重要かつ一般的に使用されるキーワードであり、type は決して C/C の typedef にのみ対応するものではありません。型の使い方には型エイリアスと型定義の2つがありますが、おなじみのC言語(defineとtypedef)風味でしょうか。

#型定義

type Student struct {
  name String
  age int
}
type I int

型別名

type Sdt = Student
type I = int

型には次の用途があります:

構造の定義

インターフェイスの定義

型定義

型エイリアス

型クエリ

構造の定義

構造体はユーザー定義の抽象データ構造です。golang の構造体は Java 言語のクラスに似ています。プログラミングにおいて決定的な役割を果たします。構造体の使用法については、struct キーワードで詳しく説明します。構造体を定義するための構文形式を見てみましょう。

type name struct {
    Field1  dataType
    Field2  dataType
    Field3  dataType
}

インターフェイスの定義

インターフェイス関連の知識ポイントは、以下のインターフェイス キーワードで詳しく紹介されます。インターフェイスを定義するための構文形式を確認してください:

type name interface{
    Read()
    Write()
}

型定義

型定義を使用して定義された型は元の型と異なるため、新しい型変数は使用できませんキャストが使用されない限り、元の型の変数に値を割り当てるために使用されます。文字列型に基づいて新しい型を定義するサンプル コードを見てみましょう。新しい型の名前は name:

type name string

なぜ型定義を使用するのですか?

型定義では、元の型に基づいて新しい型を作成できます。場合によっては、次のサンプル コードのように、コードをより簡潔にすることができます:

package main
import (
  "fmt"
)
// 定义一个接收一个字符串类型参数的函数类型
type handle func(str string)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello")
}
func main() {
  // 定义一个函数类型变量,这个函数接收一个字符串类型的参数
  var p = func(str string) {
    fmt.Println("first", str)
  }
  exec(p)
  // 匿名函数作为参数直接传递给exec函数
  exec(func(str string) {
    fmt.Println("second", str)
  })
}

出力情報は次のとおりです。

first hello
second hello

上記の例は型定義を単純に応用したものですが、型定義を使用しない場合、上記例の機能を実現したい場合はどのようにコードを書けばよいのでしょうか?

// exec函数,接收handle类型的参数
func exec(f func(str string)) {
  f("hello")
}

exec 関数のパラメータの型を func (str string) に置き換える必要があります。一見複雑ではありませんが、exec が 5 つのパラメータを必要とする関数変数を受け取った場合はどうなるでしょうか。パラメーターのリストが非常に長くなるように感じますか?

func exec(f func(str string, str2 string, num int, money float64, flag bool)) {
  f("hello")
}

上記のコードを見ると、exec関数のパラメータリストの可読性が悪くなっていることが分かります。型定義を使用してこの関数を実装する方法を見てみましょう。

package main
import (
  "fmt"
)
// 定义一个需要五个参数的函数类型
type handle func(str string, str2 string, num int, money float64, flag bool)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello", "world", 10, 11.23, true)
}
func demo(str string, str2 string, num int, money float64, flag bool) {
  fmt.Println(str, str2, num, money, flag)
}
func main() {
  exec(demo)
}

型エイリアス

型エイリアス この機能は golang1.9 で導入されました。型エイリアスを使用して定義された型は、元の型と同じです。つまり、元の型の変数に割り当てることができ、元の型のすべてのメソッド セットを持ちます。 strng 型にエイリアスを付けます。エイリアス名は name です:

type name = string

型エイリアスと型定義の違いは、型エイリアスを使用するには、エイリアスと元の型の間に代入記号 (=) を追加する必要があることです。 type エイリアスによって定義された型は元の型と同等ですが、その型を使用して定義された型は新しい型です。

次の例:

package main
import (
  "fmt"
)
type a = string
type b string
func SayA(str a) {
  fmt.Println(str)
}
func SayB(str b) {
  fmt.Println(str)
}
func main() {
  var str = "test"
  SayA(str)
  
  //错误参数传递,str是字符串类型,不能赋值给b类型变量
  SayB(str)
}

このコードは、コンパイル時に次のエラーを引き起こします:

.\main.go:21:6: cannot use str (type string) as type b in argument to SayB

エラー メッセージから、str は文字列型であることがわかります。 b 型とみなされます。パラメータは SayB 関数に渡されます。ただし、str は型パラメーターとして SayA 関数に渡すことができます。型エイリアスを使用して定義された型は元の型と一致していますが、型定義によって定義された型は新しい型であることがわかります。

型エイリアスにメソッドを追加すると、元の型メソッド セットに追加されます

型エイリアスにメソッドを追加すると、元の型でもこのメソッドを使用できるようになります。以下のサンプル コードを参照してください。

package main
import (
  "fmt"
)
// 根据string类型,定义类型S
type S string
func (r *S) Hi() {
  fmt.Println("S hi")
}
// 定义S的类型别名为T
type T = S
func (r *T) Hello() {
  fmt.Println("T hello")
}
// 函数参数接收S类型的指针变量
func exec(obj *S) {
  obj.Hello()
  obj.Hi()
}
func main() {
  t := new(T)
  s := new(S)
  exec(s)
  // 将T类型指针变量传递给S类型指针变量
  exec(t)
}

出力情報は次のとおりです。

T hello
S hi
T hello
S hi

上記の例では、S は元の型で、T は S 型のエイリアスです。 Hello メソッドを T に追加すると、S 型の変数でも Hello メソッドを使用できるようになります。型エイリアスにメソッドを追加すると、元の型でもこのメソッドを使用できることに注意してください。この例からわかるように、変数 t は S 型変数 s に代入できるため、型エイリアスは本質的には何も変更せずに、元の型のニックネームになります。

型エイリアスは、同じパッケージ内のカスタム型にのみ影響します。たとえば、golang sdk には多くのパッケージがありますが、型エイリアスを使用して、sdk パッケージ内の構造型に新しいメソッドを追加できますか?答えはいいえだ。 1 つのことに留意してください: 型エイリアスはパッケージ内の型にのみ影響します。型エイリアスがパッケージ外の型に使用されている場合、コンパイル中に次の情報が要求されます:

cannot define new methods on non-local type string

Type query

型クエリは、変数に基づいて変数の型をクエリします。なぜそのような必要があるのでしょうか? goalng には特別なタイプのインターフェイス{}があります。このタイプは、任意のタイプの変数に割り当てることができます。どのタイプの変数がインターフェイス タイプの変数に割り当てられているかを知りたい場合は、タイプ クエリを使用してこれを解決する必要があります。{}サンプルコードは次のとおりです:

package main
import (
  "fmt"
)
func main() {
    // 定义一个interface{}类型变量,并使用string类型值”abc“初始化
    var a interface{} = "abc"
    
    // 在switch中使用 变量名.(type) 查询变量是由哪个类型数据赋值。
    switch v := a.(type) {
    case string:
      fmt.Println("字符串")
    case int:
        fmt.Println("整型")
    default:
      fmt.Println("其他类型", v)
    }
}

タイプ .(type) クエリの変数がインターフェイス{} タイプではない場合、コンパイル中に次のエラーが報告されます:

cannot type switch on non-interface value a (type string)

switch. (type) の外部で使用される場合、コンパイル中に次のエラーが表示されます:

use of .(type) outside type switch

したがって、type クエリに type を使用する場合、これは switch でのみ使用でき、変数の型は使用されます。 type クエリの場合は、interface である必要があります。{}

PHP 中国語 Web サイトには、無料の

Golang 入門チュートリアル が多数あり、誰でも学習できます。

以上がgolang のタイプとはどういう意味ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。