GO 基础语法加强2

1. interface、模拟用户服务;

  • class 代表类、interface 代表接口。前者是对业务对象的封装或定义、后者是对业务对象的抽象
  • 这些在 golang 里对应的是:structinterface

抽象

  • 抽象是具象的相对概念,是就多种事物抽出其共通之点,加以综合而成的一个新的概念,此概念叫抽象

  • 程序层面
    在这里插入图片描述
    在这里插入图片描述

  • 文件 /Users/go/go2/src/Object/Iservice.go

package Object

type IService interface {
	Save()
}
  • 文件 /Users/go/go2/src/Object/UserService.go
package Object

import "log"

type UserService struct {

}

func NewUserService() *UserService {
	return &UserService{}
}

// 类方法
func(this *UserService) Save(){
	log.Println("用户保存入库成功")
}

  • 文件 /Users/go/go2/src/Object/ProductService.go
package Object

import "log"

type ProductService struct {

}

func NewProductService() *ProductService {
	return &ProductService{}
}

// 类方法
func(this *ProductService) Save(){
	log.Println("商品保存入库成功")
}

  • 文件 /Users/go/go2/src/main.go
package main

import . "goplus/src/Object"

func main() {
	var service IService = NewUserService()
	service.Save()

}

2. 使用接口简化代码、链式调用;

  • 文件 /Users/go/go2/src/Object/Iservice.go
package Object

type IService interface {
	Save() IService	// 保存一般不会返回值。这里只是演示
	List() IService
}
  • 文件 /Users/go/go2/src/Object/UserService.go
package Object

import "log"

type UserService struct {

}

func NewUserService() *UserService {
	return &UserService{}
}

// 类方法,保存入库
func(this *UserService) Save() IService {
	log.Println("用户保存入库成功")
	return this
}

func(this *UserService) List() IService {
	log.Println("用户列表获取")
	return this
}
  • 文件 /Users/go/go2/src/main.go
package main

import  . "goplus/src/Object"

// 啰嗦的写法
//func SaveModel(service UserService) {
//	service.Save()
//}
//func SaveModel2(service ProductService) {
//	service.Save()
//}


//  把 save 过程封装和隐藏起来
//func SaveModel (service IService) {
//	service.Save()
//}

func SaveModel (service IService) (IService) {
	service.Save()
	return service
}

func main() {
	//s := NewUserService()
	//s.Save()

	//IService 可以代言 UserService 和 ProductService
	// var service IService = NewUserService()
	// service.Save()
	// SaveModel(service)

	// SaveModel(NewUserService())

	// 链式调用
	// SaveModel(NewUserService()).List()

	// 演示
	NewUserService().Save().List().Save().List()

}

3. 使用接口简化代码、传递接口参数和断言;

  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id int
	Name string
	Gender byte
}

// 有选择性的进行赋值(可变参数,参数类型是 function)
func NewUser(fs  ...UserAttrFunc) (*User) {
	u := new (User)
	UserAttrFuncs(fs).apply(u)
	return u
}
  • 文件 /Users/go/go2/src/Object/UserAttrs.go
package Object

type UserAttrFunc func(*User)	// 用来设置 User 属性的函数类型,参数可省略

type UserAttrFuncs []UserAttrFunc

func (this UserAttrFuncs) apply (u *User){
	for _, f := range this {
		f(u)
	}
}

func WithUserId(id int) (UserAttrFunc) {
	return func(u *User) {
		u.Id = id
	}
}

func WithUserName(name string) (UserAttrFunc) {
	return func(u *User) {
		u.Name = name
	}
}

func WithUserGender(gender byte) (UserAttrFunc) {
	return func(u *User) {
		u.Gender = gender
	}
}
  • 文件 /Users/go/go2/src/Object/Iservice.go
package Object

type IService interface {
	Save(data interface{}) IService	// interface 通用类型
	List() IService
}
  • 文件 /Users/go/go2/src/Object/UserService.go
package Object

import "log"

type UserService struct {

}

func NewUserService() *UserService {
	return &UserService{}
}

// 类方法,保存入库
// 断言:针对 interface 进行的 类型判断
func(this *UserService) Save(data interface{}) IService {
	// 通过断言获取 user 真实的值
	if user, ok := data.(*User); ok {
		log.Printf("%v", user.Name)	// 打印值
		log.Println("用户保存入库成功")
	} else {
		log.Fatal("用户参数错误")
	}

	return this
}

func(this *UserService) List() IService {
	log.Println("用户列表获取")
	return this
}

  • 文件 /Users/go/go2/src/main.go
package main

import  . "goplus/src/Object"


func main() {

	user := NewUser(
		WithUserName("hua"),
		WithUserId(202),
		WithUserGender(1),
		)

	NewUserService().Save(user)

}

4. 反射入门、获取 Struct 所有属性、Elem 函数;

反射:

  • 运行时动态获取或设置变量的各种信息,比如变量的类型(type)、类别(kind)、值(value)

  • 两个典型方法:

  • reflect.TypeOf(变量):专门用来处理类型

  • reflect.ValueOf(变量):专门用来处理值

  • 另:Elem 函数:用来获取指针指向的变量,前提是传入的参数必须是指针才行

  • 文件 /Users/go/go2/src/main.go

package main

import (
	"fmt"
	"reflect"
)

type User struct {
	UserId int
	UserName string

}

func main() {
	// 获取对象
	//u := User{}
	//
	//t := reflect.TypeOf(u)
	//
	//fmt.Println(t.Name())	// User
	//fmt.Println(t.NumField())	// 多少属性:2
	//
	 打印属性名
	//for i :=0 ; i< t.NumField(); i++ {
	//	fmt.Println(t.Field(i).Name, t.Field(i).Type)
	//	//UserId int
	//	//Username string
	//}

	u := &User{}
	t := reflect.TypeOf(u)

	t = t.Elem()	// 把 t 变成了指针指向的变量
	for i :=0 ; i< t.NumField(); i++ {
		fmt.Println(t.Field(i).Name, t.Field(i).Type)
	}

}

5. Kind函数、获取struct属性值的两种方式;

  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"reflect"
)

type User struct {
	UserId int
	UserName string
}

func main() {
	u := &User{101, "hua"}
	// u := User{}	// 下面的 if 判断很重要
	t := reflect.ValueOf(u)

	// 地址类型,写Ptr
	if t.Kind() == reflect.Ptr {
		t = t.Elem()	// 把 t 变成了指针指向的变量
	}

	for i :=0 ; i< t.NumField(); i++ {
		//if t.Field(i).Kind() == reflect.Int {
		//	fmt.Println(t.Field(i).Int())
		//}
		//if t.Field(i).Kind() == reflect.String {
		//	fmt.Println(t.Field(i).String())
		//}

		// interface 通用
		// 101
		// hua
		fmt.Println(t.Field(i).Interface())

	}
}

6. 利用反射设置 Struct 属性值、切片映射 Struct;

  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"reflect"
)

type User struct {
	UserId int
	UserName string

}

func main() {
	u := &User{}
	t := reflect.ValueOf(u)

	// 地址类型,写Ptr
	if t.Kind() == reflect.Ptr {
		t = t.Elem()	// 把 t 变成了指针指向的变量
	}

	for i :=0 ; i< t.NumField(); i++ {
		// interface 通用
		// fmt.Println(t.Field(i).Interface())

		if t.Field(i).Kind() == reflect.Int {
			t.Field(i).SetInt(12)
		}

		if t.Field(i).Kind() == reflect.String {
			//t.Field(i).SetString("hua")
			t.Field(i).Set(reflect.ValueOf("hua"))
		}
	}

	fmt.Println(u)
	// &{12 hua}

}
package main

import (
	"fmt"
	"reflect"
)

type User struct {
	UserId int
	UserName string

}

func main() {
	u := &User{}
	t := reflect.ValueOf(u)

	// 地址类型,写Ptr
	if t.Kind() == reflect.Ptr {
		t = t.Elem()	// 把 t 变成了指针指向的变量
	}

	values := []interface{}{202, "zhang"}

	for i :=0 ; i< t.NumField(); i++ {
		if t.Field(i).Kind() == reflect.ValueOf(values[i]).Kind() {
			t.Field(i).Set(reflect.ValueOf(values[i]))
		}

	}

	fmt.Println(u)

}

7. 把 map 映射成 struct;

package main

import (
	"fmt"
	"reflect"
)

type User struct {
	UserId int
	UserName string

}

func Map2Struct(m map[string]interface{}, u interface{}) {
	v := reflect.ValueOf(u)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
		if v.Kind() != reflect.Struct {
			panic("must struct")
		}
		findFromMap := func(key string) interface{} {
			for k, v := range m {
				if k == key {
					return v
				}
			}
			return nil
		}
		for i :=0; i<v.NumField(); i++ {

			get_value := findFromMap(v.Type().Field(i).Name)
			if get_value != nil && reflect.ValueOf(get_value).Kind() == v.Field(i).Kind() {
				v.Field(i).Set(reflect.ValueOf(get_value))
			}
		}
	} else {
		panic("must ptr")
	}

}

func main() {
	u := &User{}
	m := map[string]interface{}{
		"id" : 123,
		"UserId": 101,
		"UserName": "hua",
		"age": 19,
	}
	Map2Struct(m,u)
	fmt.Println(u)

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于上面的引用内容,golang的基础语法学习可以参考以下几个步骤: 1. 首先,我们需要安装golang的开发环境。你可以直接进入官网(https://go.dev/)下载并安装golang的解释器。 2. 接下来,我们可以开始学习golang的语法。从上面的引用内容可以看出,golang的语法和Java的结构很相似,所以如果你之前有Java编程的经验,可以借鉴一些类比来学习。但是即使你没有Java的经验,也不用担心,golang的语法相对简单并且易于学习。 3. 另外,golang被称为“云计算时代的开发利器”,在使用过程中给人一种优雅、亲切、舒适的感觉。因此,在学习golang的过程中,你可能会发现它的语法设计和使用方式非常人性化。 综上所述,学习golang的基础语法可以通过安装开发环境、参考Java的结构以及体验其优雅、亲切、舒适的特点来进行。希望这些信息能够帮助你开始学习golang的基础语法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [一文看完golang基础语法](https://blog.csdn.net/qq_35889508/article/details/128125279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值