Go Language Basics 2

1. Golang implements the OCP design principle through the interface

  • introduce
    • OCP (Open-Closed Principle) is an important principle in the SOLID principle, which states: "Software entities should be open for extension and closed for modification ". To put it simply, it is to meet the demand changes by extending the new code without modifying the original code
package main

import "fmt"

type Pet interface {
    
    
	fly()
	sleep()
}
type Fish struct {
    
    
}

func (fish Fish) fly() {
    
    
	fmt.Printf("Fly....\n")
}
func (fish Fish) sleep() {
    
    
	fmt.Printf("Sleep...\n")
}

type Dog struct {
    
    
}

func (dog Dog) fly() {
    
    
	fmt.Printf("fly..\n")
}
func (dog Dog) sleep() {
    
    
	fmt.Printf("sleep..\n")
}

type Person struct {
    
    
}

func (person Person) care(pet Pet) {
    
    
	pet.fly()
	pet.sleep()
}
func main() {
    
    
	dog := Dog{
    
    }
	fish := Fish{
    
    }
	person := Person{
    
    }
	person.care(dog)
	person.care(fish)

}

2. How does golang simulate the properties and methods in OOP

  • What is OOP
    • OOP stands for Object-Oriented Programming. It is a paradigm of computer programming
  • The go language does not have object-oriented programming, but we can simulate the properties and methods of OOP through structure and function binding , that is, the receiver method
    . Although Go language is a process-oriented programming language, it can also use structure and function binding Methods to implement properties and methods similar to OOP.

First, we can use the structure (struct) in the Go language to define a custom type that contains properties . For example:

type Person struct {
    
    
    Name string
    Age int
}

The above code defines a Person type, which contains two properties: Name and Age. You can use the "." operator to access the fields in the structure.

Next, we can add methods to this structure to implement methods similar to those in OOP . Methods in the Go language also need to be implemented depending on the structure, so when defining a method, it needs to be bound to a certain structure type. For example:

func (p *Person) SayHello() {
    
    
    fmt.Printf("Hi, my name is %s and I'm %d years old.\n", p.Name, p.Age)
}

The above code defines a SayHello() method, which receives a pointer to the Person type as the receiver (receiver), and outputs the attribute information of the Person object.

Through the above methods, we can simulate the properties and methods similar to OOP in Go language. At the same time, due to the characteristics of the Go language, more flexible programming effects can be achieved through other methods such as interfaces (interfaces) and anonymous structures (anonymous struct), without losing the simplicity and efficiency of the Go language itself.


3.golang inheritance

  • The go language does not have OOP nesting, but inheritance can be achieved through nesting of structures
  • When there are fields or methods with the same name in the embedded structure , the outer structure will give priority to using its own fields or methods.
package main

import "fmt"

type Action interface {
    
    //定义接口
	eat()
	sleep()
}
type Animal struct {
    
    //定义结构体
	name string
	age  int
}
type Dog struct {
    
    
	A     Animal//继承方法
	color string
}
type Cat struct {
    
    
	Animal//继承方法,即可以不用Cat声明调用接口
	color string
}
//声明接口函数
func (animal Animal) eat() {
    
    
	fmt.Printf("%v eat...\n", animal.name)
}
func (animal Animal) sleep() {
    
    
	fmt.Printf("%v sleep...\n", animal.name)
}
func main() {
    
    
	dog := Dog{
    
    
		A:     Animal{
    
    "Tom", 12},
		color: "Red",
	}
	cat := Cat{
    
    
		Animal{
    
    "Mike", 45},
		"Blue",
	}
    //使用继承
	dog.A.eat()
	dog.A.sleep()
	cat.eat()
	cat.sleep()
	fmt.Printf("%v\n", dog.A.name)
}

4. golang constructor

  • There is no constructor (Constructor) in the Go language like other object-oriented programming languages , but we can use the factory function of the structure (struct) type to simulate the behavior of the constructor.
  • factory function
    • A variable needs to be initialized, usually by defining a function that returns that type
    • We can simulate the behavior similar to the constructor , so that we can initialize variables of custom types .
    • Purpose: easy to initialize
      insert image description here

5. Golang package

  • introduce
    • The package can distinguish the command space (two files with the same name cannot be in one file), and can also better manage the project. To create a package in go, generally create a folder, and in the go file in the folder, use the packagekeyword Declare the package name, usually, the folder name is the same as the package name, and there is only one package under the same file
  • Precautions
    • There can only be one under a folderpackage
      • importThe latter is actually GOPATHthe beginning of the relative directory path, including the last paragraph. But since there can only be one package in a directory, importa path is equal to importthe package under this path
    • For example, you have implemented a computer package, named calc, located calcin the directory; but you want to use a 1 usage example for others, calcso you can create an example subdirectory, and there is an example.go(calc/ example/example.go), at this time, example.go can be the main package, which can also have a main function
    • A package file cannot be in multiple folders
      • If a go file needs to use packages with the same name in different directories at the same time,
        1. importSpecify a package alias for each directory in these directories;
        • import ( p1 "github.com/username/repo/pkg1" p2 "github.com/username/otherrepo/pkg1" )p1.Func(), and can be used in subsequent code p2.Func()to call two different functions.
      • 2. Use absolute path to import
  • The essential:
    • How to extend system types or other types
      • 1. Define an alias
      • 2. Use composition or inline
    • Use composition or inline
      • Types that extend other people's packages can be implemented through composition or embedding . Specifically, if you want to extend a type in a package, you can create a new struct type and then embed the original type as a field in the new struct type .

      • For example, suppose you want to extend the type "Foo" in a package called "mypackage", you can do it as follows:

      • Import the "mypackage" package in your code.

        import "mypackage"
        

        Create a new struct type with "mypackage.Foo" as an embedded field.

        type MyFoo struct {
                  
                  
        	mypackage.Foo
        }
        

        Extend the "mypackage.Foo" type with the new struct type in your code.

        var myFoo MyFoo
        myFoo.Bar() // 调用"mypackage.Foo"类型中的"Bar"方法
        myFoo.MyMethod() // 调用扩展类型中新增的"MyMethod"方法
        

        1. It should be noted that if the type you want to extend is private (that is, the first letter is lowercase), you can only extend it in the same package, and cannot extend it in an external package .
        2. It should be noted that when you use combination or embedding to extend the type, ifIf new methods or fields with the same name are added, they will override the methods or fields with the same name in the original type. Therefore, special care needs to be taken when naming new methods or fields to avoid unexpected behavior.

        package main
        
        import "fmt"
        
        type Person struct {
                  
                  
        	Name string
        	Age  int
        }
        
        func (p *Person) SayHello() {
                  
                  
        	fmt.Printf("Hello, my name is %s and I'm %d years old.\n", p.Name, p.Age)
        }
        
        type Employee struct {
                  
                  
        	Person     // 嵌入"Person"类型(使用了语法糖,也可以写成 person Person,给一个变量名,但是会增加代码量)
        	Department string
        }
        
        func (e *Employee) Work() {
                  
                  
        	fmt.Printf("%s is working in %s department.\n", e.Name, e.Department)
        }
        
        func main() {
                  
                  
        	e := Employee{
                  
                  
        		Person: Person{
                  
                  
        			Name: "John Doe",
        			Age:  30,
        		},
        		Department: "Sales",
        	}
        	e.SayHello() // 调用"Person"类型中的"SayHello"方法
        	e.Work()     // 调用"Employee"类型中新增的"Work"方法
        }
        
    • Define aliases (types cannot be extended)

6. Golang dependency management

  • The key go mod(commonly used and easy to use) (I don't quite understand what I wrote, watch the video by myself)

      Go mod 是 Go 语言官方提供的模块化开发工具,用于管理 Go 项目的依赖关系和版本控制。
    
      使用 Go mod 可以方便地创建和管理模块,同时自动解决依赖关系和版本控制。下面是 Go mod 的使用方式:
    
      初始化模块
      在项目根目录下执行以下命令,将当前目录设为一个新的模块:
    
      go mod init <module-name>
      其中,<module-name> 是模块的名称,通常是一个域名或者一个 GitHub 仓库地址。
    
      例如,如果要将当前目录设为名为 "example.com/hello" 的模块,可以使用以下命令:
    
      go mod init example.com/hello
      执行该命令后,Go 会为该模块创建一个 go.mod 文件,用于记录模块的名称、版本和依赖关系。
    
      添加依赖
      使用以下命令来添加依赖:
    
      go get <package-path>
      例如,如果要添加依赖于 github.com/gin-gonic/gin 的包,可以使用以下命令:
    
      go get github.com/gin-gonic/gin
      Go 会自动下载并安装该包,并将其添加到 go.mod 文件中。
    
      更新依赖
      使用以下命令来更新依赖:
    
      go get -u <package-path>
      例如,如果要更新依赖于 github.com/gin-gonic/gin 的包,可以使用以下命令:
    
      go get -u github.com/gin-gonic/gin
      Go 会自动下载并安装最新版本的该包,并将其更新到 go.mod 文件中。
    
      删除依赖
      使用以下命令来删除依赖:
    
      go mod tidy
      执行该命令后,Go 会自动删除未使用的依赖,并更新 go.mod 文件。
    
      构建项目
      使用以下命令来构建项目:
    
      go build
      Go 会自动解决依赖关系,并编译项目。
      以上就是 Go mod 的基本使用方式,更多高级用法可以参考 Go 官方文档。
    

Guess you like

Origin blog.csdn.net/JUIU9527/article/details/130898414