Examples of the use of structs, interfaces and methods.
go mod used
go mod init github.com/zinuhe/golang-struct-interface
- Structs
1.1. Nested - Interfaces
- Methods
- Mocks
It’s idiomatic to encapsulate new struct creation in constructor functions
Structs are mutable
Ways to declare and use structs
type person struct{
name string
age int
grades []int
}
var p = person{
name: "John",
age: 30,
grades: []int{ 7, 8, 9},
}
var p person
c := new(person)
// This allocates memory for all the fields, sets each of them to their zero value
// and returns a pointer *person
p := person{name: "Sean", age: 50, grades: []int{1,2,3}}
p := person{"Sean", 50, []int{7,8,9} }
p := person{name: "jimmy"}
p.age = 42
POINTERS OF STRUCT We can create pointers of a struct using the address-of operator(&).
package main
import (
"fmt"
)
type Student struct {
name string
}
func main() {
ptrStudent := &Student{name: "John"}
fmt.Println(ptrStudent) // prints &{John}
}
// An '&' prefix yields a pointer to the struct.
fmt.Println(&person{name: "Ann", age: 40})
func newPerson(name string) *person {
p := person{name: name}
p.age = 42
return &p
}
p := newPerson("Jon")
type text string
type number int
func main() {
var t text
t = "aa"
t.print()
var x number
x = 11
x.print()
}
func (t text) print() {
fmt.Println("text:",t)
}
func (n number) print() {
fmt.Println("number",n)
fmt.Println(n.sum(5,5))
fmt.Println(n.operation(5))
}
func (n number) sum(a int, b int) int {
return a + b
}
func (n number) operation(p int) int {
tmp := p * p
tmp = tmp + n.sum(5, 5)
return tmp
}
package main
import "fmt"
type Logger struct{}
func (logger *Logger) Log(message string) {
fmt.Println(message)
}
type HttpClient struct {
logger *Logger
}
func (client *HttpClient) Get(url string) string {
client.logger.Log("Response from Logger:" + url)
return "Response from Get:" + url
}
func main() {
var lg Logger
lg.Log("Log")
var hc HttpClient
var ms = hc.Get("Get")
fmt.Println("ms:", ms)
}
package main
import (
"fmt"
)
type User struct {
name string
}
type Service struct {
name string
user User
}
func main() {
google := Service{
name: "Google",
user: User{
name: "John Doe",
},
}
// accessing from nested struct
fmt.Println(google.user.name) // prints "John Doe"
}
For reference
Go by example: Structs
golang-book
An interface is two things:
It is a set of methods (Interfaces are named collections of method signatures), but it is also a type
To implement an interface in Go, we just need to implement all the methods in the interface.
If a variable has an interface type, then we can call methods that are in the named interface. A variable of type interface can hold any value which implements the interface. This property of interfaces is used to achieve polymorphism in Go.
The interface{}
type
The interface{} type is the interface that has no methods. Since there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface. That means that if you write a function that takes an interface{}
value as a parameter, you can supply that function with any value.
package main
import (
"fmt"
)
func PrintAll(vals []interface{}) {
for _, val := range vals {
fmt.Println(val)
}
}
func main() {
names := []string{"stanley", "david", "oscar"}
vals := make([]interface{}, len(names))
for i, v := range names {
vals[i] = v
}
PrintAll(vals)
}
That’s pretty ugly.
We say that something satisfies this interface (or implements this interface) if it has a method with the exact signature String() string
.
type Stringer interface {
String() string
}
type Book struct {
Title string
Author string
}
func (b Book) String() string {
return fmt.Sprintf("Book: %s - %s", b.Title, b.Author)
}
The following Count type also satisfies the fmt.Stringer
interface — again because it has a method with the exact signature String() string
.
type Count int
func (c Count) String() string {
return strconv.Itoa(int(c))
}
For reference
Go by example: Interfaces
How to use interfaces in Go
interfaces-explained
Go supports methods defined on struct types.
This area method has a receiver type of *rect
.
type rect struct {
width, height int
}
func (r *rect) area() int {
return r.width * r.height
}
Methods can be defined for either pointer or value receiver types. Here’s an example of a value receiver.
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
For reference Go by example: Methods
[Check this](https://stackoverflow.com/questions/68100402/how-to-write-unit-test-in-golang-usng-echo-for-end-point-url-using-go-mock-gen-m)
[Check](https://dev.to/techschoolguru/mock-db-for-testing-http-api-in-go-and-achieve-100-coverage-4pa9)