结构体入门

hello world

结构体创建

向其中赋值的示例

type Book struct {  
    Title      string  
    Author     string  
    Year       int  
    CheckedOut bool  
}  
  
func main() {  
    b1 := Book{}  
    info := []byte(`{"Title":"a","Author":"b", "Year": 1, "CheckedOut": false}`)  
    _ = json.Unmarshal(info, &b1)  
  
    fmt.Printf("book title is %s", b1.Title)  
}

go 的json unmarshal 是可以只将部署值传过去的,示例


const myData = `{
		"name":"alex",
		"age":3012312123423423421
	}`

type myObj struct {
	Age int64 `json:"age"`
}

func main() {
	//obj := make(map[string]interface{})
	obj := myObj{}
	_ = json.Unmarshal([]byte(myData), &obj)
	data, _ := json.Marshal(obj)
	fmt.Println(string(data))
}

结构体方法

通过字符串返回

func (b *Book) printName() string {  
    returnMsg := "print name book title: " + b.Title  
    return returnMsg  
}  
  
func main() {  
    b1 := Book{}  
    info := []byte(`{"Title":"a","Author":"b", "Year": 1, "CheckedOut": false}`)  
    _ = json.Unmarshal(info, &b1)  
  
    getBookTitle := b1.printName()  
  
    fmt.Println(getBookTitle)  
}

通过地址返回

type Book struct {  
    Title      string  
    Author     string  
    Year       int  
    CheckedOut bool  
}  
  
func (b *Book) printName() *string {  
    returnMsg := "print name book title: " + b.Title  
    return &returnMsg  
}  
  
func main() {  
    b1 := Book{}  
    info := []byte(`{"Title":"a","Author":"b", "Year": 1, "CheckedOut": false}`)  
    _ = json.Unmarshal(info, &b1)  
  
    getBookTitle := *b1.printName()  
  
    fmt.Println(getBookTitle)  
}

通过地址返回也可以这么写

b1 := Book{}  
info := []byte(`{"Title":"a","Author":"b", "Year": 1, "CheckedOut": false}`)  
_ = json.Unmarshal(info, &b1)  
  
getBookTitle := b1.printName()  
  
fmt.Println(*getBookTitle)

值接收器和指针接收器

无论是值接收器,还是指针接收器,都可以给 struct 添加方法,只是值接收器里的函数,是将结构体实例化的对象拷贝了一份,对副本操作。而指针接收器,则是直接操作结构体实例化对象,能直接修改这个对象本身的属性。一个示例如下

  
type Rectangle struct {  
    Width  float64  
    Height float64  
}  
  
func (r Rectangle) Area() float64 {  
    return r.Width * r.Height  
}  
  
func (r *Rectangle) Scale(factor float64) {  
    r.Width *= factor  
    r.Height *= factor  
}  
  
func main() {  
    rec := &Rectangle{  
       Width:  4,  
       Height: 5,  
    }  
    originalArea := rec.Area()  
    fmt.Printf("original area was %f\n", originalArea)  
  
    rec.Scale(2)  
    newArea := rec.Area()  
    fmt.Printf("new area was %f", newArea)  
}

上面是一个基本的例子,能看出来,刚开始初始化了一个 宽4高5的长方形,之后直接用值接收器的方法,获得面积。之所以这里用值传递,是因为我们没有改变这个长方形实例的任何属性,都是拿长方形实例的属性做额外的计算。之后我们在Scale方法里,修改了长方形的宽和高,由于是对长方形实例本身进行操作,所以要用指针接收器。

再来一个更复杂一点的例子: 在下面的例子里,我们定义了 Book 和 Library,其中Library 的 Books是一个切片,Library结构体有AddBook和CheckOutBook方法,当AddBook的时候,会将书添加到Books切片里,当CheckOutBook的时候,会从Books 切片里移除这本书。Book结构体本身只有一个DisplayInfo的方法,将书的信息打印出来。


type Book struct {  
    Title      string  
    Author     string  
    Year       int  
    CheckedOut bool  
}  
  
type Library struct {  
    Books []Book  
}  
  
func (b Book) DisplayInfo() {  
    fmt.Printf("Title: %s, Author: %s, Year: %d, CheckedOut: %t\n", b.Title, b.Author, b.Year, b.CheckedOut)  
}  
  
func (l *Library) AddBook(b Book) {  
    l.Books = append(l.Books, b)  
}  
  
func (l *Library) CheckOutBook(BookName string) {  
    for i := range l.Books {  
       if l.Books[i].Title == BookName && !l.Books[i].CheckedOut {  
          l.Books[i].CheckedOut = true  
          fmt.Printf("successfully checked out: %s \n", l.Books[i].Title)  
          return  
       }  
    }    fmt.Printf("Book not found or already checked out %s \n", BookName)  
}  
  
func main() {  
    myLibrary := &Library{}  
    b1 := Book{  
       Title:      "The Go Programming Language",  
       Author:     "Alan A. A. Donovan",  
       Year:       2015,  
       CheckedOut: false,  
    }  
    b2 := Book{  
       Title:      "The Pragmatic Programmer",  
       Author:     "Andrew Hunt",  
       Year:       1999,  
       CheckedOut: false,  
    }  
    myLibrary.AddBook(b1)  
    myLibrary.AddBook(b2)  
  
    borrow := "The Go Programming Language2"  
    fmt.Printf("checking out %s\n", borrow)  
    myLibrary.CheckOutBook(borrow)  
}

最后更新于