wordpress免费,南京企业网站seo,免费网站建设总部,有专门做检验的视频网站吗加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号#xff1a;96933959结构体structstruct 用来自定义复杂数据结构#xff0c;可以包含多个字段(属性)#xff0c;可以嵌套#xff1b;go中的struct类型理解为类#xff0c;可以定义方法#xff0c;和函数定义有些许区…加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号96933959结构体structstruct 用来自定义复杂数据结构可以包含多个字段(属性)可以嵌套go中的struct类型理解为类可以定义方法和函数定义有些许区别struct类型是值类型。struct定义type User struct{NamestringAge int32messstring}varuser Uservar user1 *User User{}var user2 *User new(User)struct使用下面示例中user1和user2为指针类型访问的时候编译器会自动把 user1.Name 转为 (*user1).Namefunc main() {varuser Useruser.Name nickuser.Age 18user.mess lovervar user1 *User User{Name:dawn,Age:21,}fmt.Println(*user1) //{dawn 21 }fmt.Println(user1.Name, (*user1).Name) //dawn dawnvar user2 *User new(User)user2.Name suoninguser2.Age 18fmt.Println(user2)//{suoning 18 }fmt.Println(user2.Name, (*user2).Name) //suoning suoning}构造函数golang中的struct没有构造函数可以伪造一个type User struct{NamestringAge int32messstring}func NewUser(namestring, age int32, mess string) *User {return User{Name:name,Age:age,mess:mess}}func main() {//user : new(User)user : NewUser(suoning, 18, lover)fmt.Println(user, user.mess, user.Name, user.Age)}内存布局struct中的所有字段在内存是连续的布局如下varuser Useruser.Name nickuser.Age 18user.mess loverfmt.Println(user)//{nick 18 lover}fmt.Printf(Name:%p\n, user.Name) //Name:0xc420016180fmt.Printf(Age: %p\n, user.Age) //Age: 0xc420016190fmt.Printf(mess:%p\n, user.mess) //mess:0xc420016198 8字节为内存对齐方法方法是作用在特定类型的变量上因此自定义类型都可以有方法而不仅仅是struct。方法的访问控制也是通过大小写控制。init函数是通过传入指针实现这样改变struct字段值因为是值类型。type User struct{NamestringAgeintsexstring}func (this *User) init(name string, age int, sex string) {this.Name namethis.Age agethis.sex sex}func (this User) GetName() string{return this.Name}func main() {varuser Useruser.init(nick, 18, man)//(user).init(nick, 18, man)name :user.GetName()fmt.Println(name)}匿名字段如果有冲突的 则最外的优先type User struct{Name stirngAgeint}type Loverstruct{Usersex time.TimeintAgeint}继承 多重继承一个结构体继承多个结构体访问通过点。继承字段以及方法。可以起别名如下面 u1(user1)访问 user.u1.Age。如果继承的结构体都拥有同一个字段通过user.name访问就会报错必须通过user.user1.name来访问。type user1 struct{namestringAgeint}type user2struct{namestringageintsex time.Time}type Userstruct{u1 user1//别名user2NamestringAgeint}func main() {varuser Useruser.Name nickuser.u1.Age 18fmt.Println(user)//{{ 18} { 0 {0 0 }} nick 0}}tag在go中首字母大小写有特殊的语法含义小写包外无法引用。由于需要和其它的系统进行数据交互例如转成json格式。这个时候如果用属性名来作为键值可能不一定会符合项目要求。tag在转换成其它数据格式的时候会使用其中特定的字段作为键值。import encoding/jsontype Userstruct{Namestring json:userNameAgeint json:userAge}func main() {varuser Useruser.Name nickuser.Age 18conJson, _ :json.Marshal(user)fmt.Println(string(conJson)) //{userName:nick,userAge:0}}String()如果实现了String()这个方法那么fmt默认会调用String()。type name1 struct{intstring}func (this *name1) String() string{return fmt.Sprintf(This is String(%s)., this.string)}func main() {n : new(name1)fmt.Println(n)//This is String().n.string suoningd : fmt.Sprintf(%s, n) //This is String(suoning).fmt.Println(d)}defer所有错误func myE() (str string, err error) {defer func() {if p : recover(); p !nil {str, ok : p.(string)ifok {errerrors.New(str)}else{err errors.New(panic)}//debug.PrintStack()}}()panic(this is panic message)return hello girl, err}接口InterfaceInterface类型可以定义一组方法但是这些不需要实现。并且interface不能包含任何变量。interface类型默认是一个指针。Interface定义type Car interface{NameGet()stringRun(nint)Stop()}Interface实现Golang中的接口不需要显示的实现。只要一个变量含有接口类型中的所有方法那么这个变量就实现这个接口。因此golang中没有implement类似的关键字如果一个变量含有了多个interface类型的方法那么这个变量就实现了多个接口如果一个变量只含有了1个interface的方部分方法那么这个变量没有实现这个接口。空接口 Interface{}空接口没有任何方法所以所有类型都实现了空接口。var a intvar b interface{} //空接口b a多态一种事物的多种形态都可以按照统一的接口进行操作。栗子type Car interface{NameGet()stringRun(nint)Stop()}type BMWstruct{Namestring}func (this *BMW) NameGet() string{return this.Name}func (this *BMW) Run(n int) {fmt.Printf(BMW is running of num is %d \n, n)}func (this *BMW) Stop() {fmt.Printf(BMW is stop \n)}type Benzstruct{Namestring}func (this *Benz) NameGet() string{return this.Name}func (this *Benz) Run(n int) {fmt.Printf(Benz is running of num is %d \n, n)}func (this *Benz) Stop() {fmt.Printf(Benz is stop \n)}func (this *Benz) ChatUp() {fmt.Printf(ChatUp \n)}func main() {varcar Carfmt.Println(car)//var bmw BMW BMW{Name: 宝马}car bmwfmt.Println(car.NameGet())//宝马car.Run(1) //BMW is running of num is 1car.Stop() //BMW is stopbenz : Benz{Name: 大奔}carbenzfmt.Println(car.NameGet())//大奔car.Run(2) //Benz is running of num is 2car.Stop() //Benz is stop//car.ChatUp()//ERROR: car.ChatUp undefined (type Car has no field or method ChatUp)}Interface嵌套一个接口可以嵌套在另外的接口。即需要实现2个接口的方法。type Car interface{NameGet()stringRun(nint)Stop()}type Usedinterface{CarCheap()}类型断言类型断言由于接口是一般类型不知道具体类型如果要转成具体类型可以采用以下方法进行转换var t intvar x interface{}xty x.(int) //转成inty, ok x.(int) //转成int不报错栗子一func test(i interface{}) {//n : i.(int)n, ok : i.(int)if !ok {fmt.Println(error)return}n 10fmt.Println(n)}func main() {var t1 inttest(t1)}栗子二switch typetype Student struct{Namestring}func judgmentType(items ...interface{}) {for k, v :range items {switchv.(type) {case string:fmt.Printf(string, %d[%v]\n, k, v)case bool:fmt.Printf(bool, %d[%v]\n, k, v)case int, int32, int64:fmt.Printf(int, %d[%v]\n, k, v)casefloat32, float64:fmt.Printf(float, %d[%v]\n, k, v)caseStudent:fmt.Printf(Student, %d[%v]\n, k, v)case *Student:fmt.Printf(Student, %d[%p]\n, k, v)}}}func main() {stu1 : Student{Name: nick}judgmentType(1, 2.2, learing, stu1)}栗子三判断一个变量是否实现了指定接口type Stringer interface{String()string}type Mystructinterface{}type Mystruct2struct{}func (this *Mystruct2) String() string{return }func main() {varv Mystructvarv2 Mystruct2v v2if sv, ok :v.(Stringer); ok {fmt.Printf(%v implements String(): %s\n, sv.String());}}反射 reflectreflect包实现了运行时反射允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值通过调用TypeOf获取其动态类型信息该函数返回一个Type类型值。调用ValueOf函数返回一个Value类型值该值代表运行时的数据。func TypeOf(i interface{}) TypeTypeOf返回接口中保存的值的类型TypeOf(nil)会返回nil。func ValueOf(i interface{}) ValueValueOf返回一个初始化为i接口保管的具体值的ValueValueOf(nil)返回Value零值。reflect.Value.Kind获取变量的类别返回一个常量const(Invalid KindiotaBoolIntInt8Int16Int32Int64UintUint8Uint16Uint32Uint64UintptrFloat32Float64Complex64Complex128ArrayChanFuncInterfaceMapPtrSliceStringStructUnsafePointer)reflect.Value.Kind()方法返回的常量reflect.Value.Interface()转换成interface{}类型【变量Interface{}Reflect.Value】获取变量的值reflect.ValueOf(x).Int()reflect.ValueOf(x).Float()reflect.ValueOf(x).String()reflect.ValueOf(x).Bool()通过反射的来改变变量的值reflect.Value.SetXX相关方法比如:reflect.Value.SetInt()设置整数reflect.Value.SetFloat()设置浮点数reflect.Value.SetString()设置字符串栗子一import reflectfunc main() {var x float64 5.21fmt.Println(type:, reflect.TypeOf(x)) //type: float64v :reflect.ValueOf(x)fmt.Println(value:, v) //value: 5.21fmt.Println(type:, v.Type()) //type: float64fmt.Println(kind:, v.Kind()) //kind: float64fmt.Println(value:, v.Float()) //value: 5.21fmt.Println(v.Interface())//5.21fmt.Printf(value is %1.1e\n, v.Interface()) //value is 5.2e00y :v.Interface().(float64)fmt.Println(y)//5.21}栗子二(修改值)SetXX(x) 因为传递的是 x 的值的副本所以SetXX不能够改 x改动 x 必须向函数传递 x 的指针SetXX(x) 。//错误代码//panic: reflect: reflect.Value.SetFloat using unaddressable valuefunc main() {vara float64fv : reflect.ValueOf(a)fv.SetFloat(520.00)fmt.Printf(%v\n, a)}//正确的传指针func main() {vara2 float64fv2 : reflect.ValueOf(a2)fv2.Elem().SetFloat(520.00)fmt.Printf(%v\n, a2) //520}反射操作结构体reflect.Value.NumField()获取结构体中字段的个数reflect.Value.Method(n).Call(nil)来调用结构体中的方法栗子一(通过反射操作结构体)import reflecttype NotknownTypestruct{S1stringS2stringS3string}func (n NotknownType) String()string{return n.S1 n.S2 n.S3}var secret interface{} NotknownType{Go, C, Python}func main() {value :reflect.ValueOf(secret)fmt.Println(value)//Go C Pythontyp :reflect.TypeOf(secret)fmt.Println(typ)//main.NotknownTypeknd :value.Kind()fmt.Println(knd)//structfor i : 0; i value.NumField(); i{fmt.Printf(Field %d: %v\n, i, value.Field(i))}results : value.Method(0).Call(nil)fmt.Println(results)//[Go C Python]}栗子二(通过反射修改结构体)import reflecttype Tstruct{AintBstring}func main() {t : T{18, nick}s : reflect.ValueOf(t).Elem()typeOfT :s.Type()for i : 0; i s.NumField(); i{f :s.Field(i)fmt.Printf(%d: %s %s %v\n, i,typeOfT.Field(i).Name, f.Type(), f.Interface())}s.Field(0).SetInt(25)s.Field(1).SetString(nicky)fmt.Println(t)}/*输出0: A int 181: B string nick{25 nicky}*/import reflecttype teststruct{S1strings2strings3string}var s interface{} test{S1:s1,s2:s2,s3:s3,}func main() {val :reflect.ValueOf(s)fmt.Println(val)//{s1 s2 s3}fmt.Println(val.Elem()) //{s1 s2 s3}fmt.Println(val.Elem().Field(0)) //s1val.Elem().Field(0).SetString(hehe) //S1大写}栗子三(struct tag 内部实现)package mainimport (fmtreflect)type Userstruct{Namestring json:user_name}func main() {varuser UseruserType :reflect.TypeOf(user)jsonString : userType.Field(0).Tag.Get(json)fmt.Println(jsonString)//user_name}