1. ホーム
  2. スクリプト・コラム
  3. ゴラン

golangにおける構造体操作

2022-01-07 12:44:58

structは、オブジェクト指向の操作を実装するための重要なテクニックで、基本的には型宣言と同じです from django.contrib.auth import login url(r'^login/$',login,{'template_name'='users/login.html'},name='login') が併用されます。

structは値型なので、そのゼロ値は全メンバーのゼロ値となります。関数の引数として使用する場合、値型には制限があるため、ポインタと組み合わせて使用されることが多いようです。

宣言

from django.conf.urls import url
from django.contrib.auth.views import LoginView
urlpatterns = [
    #LoginView.as_view should be followed by ()
    url(r'^login/$',LoginView.as_view(template_name='users/login.html'),name='login')
]


1行に1メンバー、間にカンマやセミコロンは入れない、大文字のメンバーはパッケージの外にアクセスできる。

型が同じであれば、1行で定義することも検討してください。

type Employee struct {
    ID int
    Name, Address string
}

同じ名前の構造体のメンバは定義できないが,同じ名前の構造体のポインタ型のメンバは定義できる,例.

type Employee struct {
    ID int
    Name, Address string
	   Leader *Employee		
leader *Employee }

初期化

は、宣言時に直接初期化する方法と、宣言してから1つずつ代入する方法があります。まず、最も直接的な方法の一つを見てみましょう。

var empl Employee
empl.ID = 1
empl.Name = "foo"
empl.Address = "nanshan"

また、より高速に初期化することも可能です

empl2 := Employee{2, "foo", "nanshan"}

ですから、メンバーを宣言する順番はとても重要です。上で初期化された値は、構造体のメンバに一つずつ対応し、それ以上でも以下でもない、型依存の代入が可能なものでなければなりません。

structのメンバは調整されることがあるので、上記のコードでは少しもろいので、メンバ名で初期化するように改良したのが以下です。

empl3 := &Employee{
    ID: 3,
    Name: "foo",
    Address: "beijing",
}

この時点では順番は関係なく、完全である必要もなく、直接割り当てられないメンバーはゼロ値を保持し続けます。

ポインタに関連する操作

structは値型なので、引数として渡すと関数内部でコピーを受け取ることになるので、一般的には構造体へのポインタを持つ関数の引数として渡されます。

emplPtr := &empl
emplPtr.Name = "bar" // equivalent to (*emplPtr).Name = "bar"

ポインタ構造体型の変数を使用する場合は、以下のように * structは参照型のように見えますが、実際は構造体へのポインタです。

次の関数は、構造体を初期化し、そのポインタを返します。

func EmployeeById(id int) *Employee {
    return &Employee{
        ID: id,
        Name: "foo",
        Address: "beijing",
    }
}

構造体の比較可能性

構造体のすべてのメンバが比較可能である場合、構造体は比較可能です。

比較アルゴリズムは、各メンバーの値が等しい場合、2つの構造体変数は等しく、そうでない場合は等しくないというものです。

構造体の型が比較可能であれば、マップのキー型として使用できることを意味します。

構造体のネストと匿名メンバー

これは、ある構造体の内部で匿名構造体を宣言すると、この匿名構造体のメンバを使用する際に、現在の構造体がこの匿名構造体のメンバを所有しているかのように、匿名構造体の名前を省略することができるという魔法のような仕組みです。

次の構造体である EmployeeManager は、上記の構造 Employee の匿名メンバーとして

type EmployeeManager struct {
    Employee // anonymous member
    ManagerLevel int
int}

匿名メンバーを初期化する。

var manager = EmployeeManager{
    Employee: Employee{
        ID: 2,
        Name: "fooManager",
        Address: "beijing",
    },
    ManagerLevel: 4,
}

見た目は中庸で、何の不思議もありません。もう一度、この構造をどのように使うか見てみましょう。

fmt.Println(manager.ManagerLevel)
fmt.Println(manager.Name) //this line
fmt.Println(manager.Employee.Name) //equivalent to this line

このように投げかけると、単純化されるだけでなく、技術的には継承がないのに、継承のメリットを享受し、継承の手間を省くという組み合わせが見えてきますね。

匿名構造体を使用する場合、プロパティだけでなく、メソッドも直接使用することができます。

以上でgolangの構造体についての記事を終わります。golangのstructについてもっと知りたい方は、BinaryDevelopの過去の記事を検索するか、以下の関連記事を引き続きご覧ください。