GO Language Practical Embedded Type and Attribute Privacy Definition

write in front


  • Well, study GO, so I have this article

  • The content of the blog post is 《GO语言实战》one of the reading notes

  • mainly involves knowledge

    • Embed type
    • The role of privacy identifiers
  • If you don’t understand enough, please help me correct it.

There is only one true responsibility for everyone: to find themselves. Then stick to it in your heart for the rest of your life, wholeheartedly, and never stop. All other roads are incomplete, human escapes, cowardly returns to popular ideals, drifting, inner fears - Hermann Hesse, "Demian"


Embed type

Go 语言Allows users to extend or modify the behavior of existing types. It is also important when modifying existing types to conform to new types. This function is 嵌入类型(type embedding)accomplished through . Embedded types declare existing types directly in new structural types. The embedded type is called the new outer type 内部类型.

Passed 嵌入类型,与内部类型相关的标识符会提升到外部类型上.

The embedded type here means 面向对象中继承that the relevant identifiers of the internal class will be promoted to the external type, that is, similar to inheritance in object-oriented, the subclass will inherit the methods and properties of the parent class. will involve 重写and隐藏

But golangessentially there is no inheritance related syntax and concepts. Compared with Java, the difference is 支持多继承that multiple internal types can be embedded at the same time. And the outer type has no reference to the inner type. There is no superconcept of . In the overall design, it 内部类继承了一个和外部类无关的类feels like Java

In essence, embedded types are a combination relationship, the principle of synthesis and reuse, and there is no strong relationship like inheritance.

package main

import (
 "fmt"
)
type user struct {
    
    
 name  string
 email string
}

type user1 struct {
    
    
 name1 string
 name2 string
}

func (u *user) notify() {
    
    
 fmt.Printf("Sending user email to %s<%s>\n",
  u.name,
  u.email)
}
type admin struct {
    
    
 user  // Embedded Type
 user1
 level string
}
func main() {
    
    
 ad := admin{
    
    
  user: user{
    
    
   name:  "john smith",
   email: "[email protected]",
  },
  level: "super",
 }
 ad.user.notify()
 // 借助内部类型提升,notify 方法也可以直接通过 ad 变量来访问
 ad.notify()
}

Methods are called directly through variables of external types notify. Since the identifier of the internal type is promoted to the external type, we can directly call it 外部类型的值来访问内部类型的标识符, similar to inheritance in object-oriented

func main() {
    
    
 ad := admin{
    
    
  user: user{
    
    
   name:  "john smith",
   email: "[email protected]",
  },
  level: "super",
 }

 sendNotification(&ad)
}

func sendNotification(n notifier) {
    
    
 n.notify()
}

If the external type does not need to use the implementation of the internal type, it is necessary to 重写override the binding method of the internal type in the external type. This is called隐藏

package main

import (
 "fmt"
)

type notifier interface {
    
    
 notify()
}
type user struct {
    
    
 name  string
 email string
}
func (u *user) notify() {
    
    
 fmt.Printf("Sending user email to %s<%s>\n",
  u.name,
  u.email)
}
type admin struct {
    
    
 user
 level string
}
func (a *admin) notify() {
    
    
 fmt.Printf("Sending admin email to %s<%s>\n",
  a.name,
  a.email)
}
func main() {
    
    
 ad := admin{
    
    
  user: user{
    
    
   name:  "john smith",
   email: "[email protected]",
  },
  level: "super",
 }
 sendNotification(&ad)
 ad.user.notify()
 ad.notify()
}
func sendNotification(n notifier) {
    
    
 n.notify()
}

Public or undisclosed identifiers

To design a good API, you need to use some kind of rules to control it 声明后的标识符的可见性. Go language support 包里公开或者隐藏标识符allows users to control the visibility of identifiers according to their own rules

  • When an identifier's name 小写字母begins 未公开with
  • If an identifier begins 大写字母with , the identifier 公开is
package counters

type alertCounter int

For undisclosed properties, assignment can be done using a method similar to a factory function.

package counters

type alertCounter int

func New(value int) alertCounter {
    
    
 return alertCounter(value)
}

You can also use setterthe method

type User struct {
    
    
  id int
  name string
}

func (u *User) SetName(name string) {
    
    
  u.name = name
}

UserTypes are declared as public types. There are two fields declared in the User type, a public field named Name and an undisclosed field named email.

package entities

// User defines a user in the program.
type User struct {
    
    
 Name  string
 email string
}

func main() {
    
    
 u := entities.User{
    
    
  Name:  "Bill",
  email: "[email protected]",
 }
 fmt.Printf("User: %v\n", u)
}

An attempt was made to initialize an undocumented field email, so the compiler complained that it was an unknown field. Because emailthis identifier is not public, it cannot entitiesbe accessed outside the package

How public and undisclosed embedded types are assigned

package entities

// user 在程序里定义一个用户类型
type user struct {
    
    
 Name  string
 Email string
}

// Admin 在程序里定义了管理员
type Admin struct {
    
    
 user   // 嵌入的类型未公开
 Rights int
}

Embedded type initialization

func main() {
    
    
 // / 创建 entities 包中的 Admin 类型的值
 a := entities.Admin{
    
    
  Rights: 10,
 }

 // 设置未公开的内部类型的
 // 公开字段的值
 a.Name = "Bill"
 a.Email = "[email protected]"

 fmt.Printf("User: %v\n", a)
}

Reference to part of the blog post

© The copyright of the reference links in this article belongs to the original author. If there is any infringement, please inform us.


"GO Language Practice"


© 2018-2023 [email protected] , All rights reserved. Keep Attribution-NonCommercial-ShareAlike (CC BY-NC-SA 4.0)

Guess you like

Origin blog.csdn.net/sanhewuyang/article/details/133279643