[Golang]StruckとPointer

16504 ワード

Sturct


StructはStructのメンバーとして使用できます
package main

import "fmt"

type Student struct {
	Name  string
	Class int
	No    int
	Score float64
}

type VIPStudent struct {
	stud  Student
	isVIP bool
}

func main() {
	var student VIPStudent

	student.stud.Name = "홍길동"
	student.isVIP = true

	fmt.Println("이름 : ", student.stud.Name)
	fmt.Println("VIP : ", student.isVIP)

}
メモリをソートすることで、ストレージスペースを効率的に使用できます.

// Not Good, 56byte
type Padding struct{
	A int8		// 8byte (padding)
    B int		// 8byte
    C float64	// 8byte
    D uint16	// 8byte (padding)
    E int		// 8byte
    F float32	// 8byte (padding)
    G int8		// 8byte
}


// Good, 32byte
type Padding struct{
	A int8		// 1byte
    G int8		// 1byte
    D uint16	// 2byte
    F float32	// 4byte
    B int		// 8byte
    C float64	// 8byte
    E int		// 8byte

}
作成時に直ちに使用する必要がある匿名構造
func main() {
	p1 := struct {
		first string
		last  string
	}{first: "James", last: "Bond"}
	fmt.Println(p1)
}
Marshaling
  • Marshalingは、データの転送またはアーカイブ時にデータを効率的な形式に変換することを意味する.
  • Go structはJSON形式または逆
  • に変換可能
    package main
    
    import (
    	"encoding/json"
    	"fmt"
    )
    
    type Employee struct {
    	Name   string `json:"empname"`
    	Number int    `json:"empid"` // number와 같이 소문자로 작성 시 json/encoding에서 파싱되지 않아 무시 됨
    }
    
    func main() {
    	employee_1 := &Employee{Name: "Dixya Lhyaho", Number: 10}
        
        // Marshal
    	e, err := json.Marshal(employee_1) // MarshalIndent 사용 시 들여쓰기가 적용됨
    	if err != nil {
    		fmt.Println(err)
    		return
    	}
        fmt.Println(e) // [123 34 101 109 112 110 97 109 101 34 58 34 68 105 120 121 97 32 76 104 121 97 104 111 34 44 34 101 109 112 105 100 34 58 49 48 125]
    	fmt.Println(string(e)) // {"empname":"Dixya Lhyaho","empid":10}
        
        // Unmarshal
    	var emp Employee
    
    	err2 := json.Unmarshal(e, &emp)
    	if err2 != nil {
    		fmt.Println(err2)
    		return
    	}
    	fmt.Println(emp.Name) // 10
    	fmt.Println(emp.Number) // Dixya Lhyaho
    }
    
    注意事項.Unmarshal vs Decode
  • json.Umarshal-byte[]を入力として
    -メモリを効率的に使用する(Decodeはjsonデータをメモリにバッファリングし、効率が悪い)
  • .
  • decoder.Decode- io.reader(file,HTTP request)を入力とします.
    -jsonデータのstream
  • へのアクセスを容易にする

    Pointer

  • 変数の転送と関数パラメータの転送は常に値をコピーし、メモリ効率とパフォーマンスの問題
  • を引き起こす.
  • ポインタはこの問題を効果的に解決した
  • package main
    
    import "fmt"
    
    type Data struct {
    	value int
    	data  [200]int
    }
    
    func ChangeData(arg *Data) {
    	arg.value = 999
    	arg.data[100] = 999
    }
    
    func main() {
    	var data Data
    
    	// 포인터로 전달하지 않으면 값이 변경되지 않음
    	ChangeData(&data)
    	fmt.Printf("value = %d\n", data.value)
    	fmt.Printf("data[100] = %d\n", data.data[100])
    }
    ポインタ変数で構造体を作成し、初期値に置き換えるには、構造体変数を作成する必要はありません.
    	// 구조체 변수 생성 및 초깃값 대입
        var data Data
        var p *Data = &data
        
        // 구조체 생성과 동시에 초깃값 대입
        var p *Data = &Data{}	// 방법 1
        var p = new(Data) 		// 방법 2
    コピーポインタはインスタンスの作成ではありません
    // 인스턴스가 추가로 생성되는 것이 아님 (인스턴스 1개, 포인터가 동일하게 가르킴)
    var p1 *Data = &Data{}
    var p2 *Data = p1
    var p3 *Data = p2
    
    // 값만 동일하고 각각 개별적인 인스턴스가 생김 (인스턴스 3개)
    var data1 Data
    var data2 Data = data1
    var data3 Data = data1
    関数の外部に公開されているインスタンスでは、関数が終了してもアクティブです.
    package main
    
    import "fmt"
    
    type User struct{
    	Name string
        Age int
    }
    
    func NewUse(name string, age int) *User{
    	// 함수 내부에서 선언이 되었지만, 외부에서도 접근이 가능함
    	var u = User{name,age}
        return &u
    }
    
    func main(){
    	userPointer := NewUse("AAA",23)
        fmt.Println(userPointer)
    }
  • メモリ割り当て時にスタックまたはスタックに格納
  • スタックは
  • で理論的により有効であるが、スタックメモリは関数内部でのみ使用され、hipは関数外部で公開される.
  • Goスタックに格納するかhipに格納するかをescape解析により決定する
  • .
  • の関数が外部公開である場合、関数終了時に
  • は消失しない.