您现在的位置是:自如初>Go基础Go基础

32、Go 结构体 - type 类型别名和用户自定义类型

温新 2023-08-30 00:16:18 Go基础 114人已围观

简介当基本的数据类型(string、int、float、bool等)不够用时,用户可以使用 type 关键字进行自定义类型。type 只有两种使用方式,一种类型别名,另一种是自定义类型。

hi,我是温新

在 Go 语言中,自定义类型指的是使用 type 关键字定义的新类型,它可以是基本类型的别名,也可以是结构体、函数等组合而成的新类型。自定义类型可以帮助我们更好地抽象和封装数据,让代码更加易读、易懂、易维护。

当基本的数据类型(string、int、float、bool等)不够用时,用户可以使用 type 关键字进行自定义类型。type 只有两种使用方式,一种类型别名,另一种是自定义类型

本篇文章将学习这两种方式。

类型别名与类型定义

类型别名

语法如下:

type TypeAlias = Type
// type 类型别名 = 类型

类型别名规定:TypeAlias 只是 Type 的别名,本质上 TypeAliasType 是同一个类型。如同李四的别名是二狗子,不不管你叫二狗子还是李四,都是他。

类型定义

语法如下:

type newType = Type
// type 新类型 = 类型

案例:

package main

import "fmt"

// 类型定义
type newInt int

// 类型别名
type newString = string

func main() {
   // 将 newStr 类型声明为 newString
   var newStr newString = "王美丽"
   // 将 num 声明为 newInt 类型
   var num newInt = 19

   fmt.Printf("newStr 的数据类型 %T,内容是 %s\n", newStr, newStr)
   fmt.Printf("num 的数据类型 %T,内容是 %d\n", num, num)
}

输出结果

newStr 的数据类型 string,内容是 王美丽
num 的数据类型 main.newInt,内容是 19


类型声明与类型定义有什么区别?

两者之间的区别在于,类型别名只是给现有类型取了一个别名;而类型定义则是完全定义了一种新的类型。

非本地类型不能定义方法

package main

import "time"

// 定义一个方法别名
type myTime = time.Time

func main() {

}

// 为 myTime 添加一个函数
func (m myTime) getMyTime() {
}

(m myTime) 这里会报错:Cannot define new methods on the non-local type 'time.Time'。不能在一个非本地的类型 time.Duration 上定义新的方法。非本地类型指的就是 time.Duration 不是在 main 包中定义的,而是在 time 包中定义的,与 main 包不在同一个包中,因此不能为不在一个包中的类型定义方法。


解决这个问题有两种方法,如下:

1、type myTime  =time.Time 修改为type myTime time.Duration,也就是把 myTime从别名改为类型;

2、把 myTime 的别名定义放在 time 包中。

用户自定义类型

在 Go 语言中,type 是一个非常重要的关键字,它的常用用法有这几种:类型别名、类型定义、定义结构体、定义接口、类型查询、定义函数。

定义结构体

在之前的文章已经学习过结构体,这里作一个简单的回顾吧。

package main

import "fmt"

func main() {
   p1 := MyPerson{
       name:   "王美丽",
       gender: "女",
   }

   fmt.Println(p1)
}

// 定义结构体
type MyPerson struct {
   name, gender string
}

定义接口

关于接口,这里只作一个简单的案例进行演示。关于接口的知识将在后续文章中学习。

package main

import "fmt"

func main() {
   xiaomi := new(Xiaomi)
   xiaomi.name = "小米13"
   xiaomi.Call() // 小米13:可以打电话
}

// 定义一个电话接口
type Phone interface {
   Call()
}

// 定义结构体
type Xiaomi struct {
   name string
}

// 定义一个方法
func (xiaomi *Xiaomi) Call() {
   fmt.Printf("%s:可以打电话", xiaomi.name)
}

定义函数

package main

import (
   "fmt"
   "strconv"
)

func main() {
   result := getMyFun()
   fmt.Println(result(10, 10))
}

// 定义一个函数
type MyFun func(int, int) string

// 该函数返回值是 MyFun 类型
func getMyFun() MyFun {
   fun := func(m, n int) string {
       str := strconv.Itoa(m) + strconv.Itoa(n)

       return str
   }

   return fun
}

类型查询

类型查询,就是根据变量来查询它的类型。Golang 中有一个特殊的类型interface{},这个类型可以被赋予任何类型的变量的值,如果想要知道哪个类型的赋值给了interface{}类型变量,就需要使用类型查询,案例如下:

package main

import "fmt"

func main() {
   var variableName interface{} = "abc"

   switch v := variableName.(type) {
   case string:
       fmt.Println("字符串")
   case int:
       fmt.Println("整型")
   default:
       fmt.Println("其他类型", v)
   }
}

如果使用.(type)查询类型的变量不是 interface{} 类型,则在编译时报错:cannot type switch on non-interface value a (type string)

若在 switch 以外的地方使用.(type),则在编译时报错:use of .(type) outside type switch

由此可知,使用type进行类型查询时,只能在switch中使用,且使用类型查询必须是interface{}


后面要停更 2 个星期了,今天把库存都发了出来。我们 9 月中旬再见。

很赞哦!(3)

文章评论

登录 注册

自如初--时间轴

站名:自如初

独白:向前走!向前走!

邮箱:ziruchu@qq.com

RSS: RSS

站点信息