美文网首页
Go基础-007 类型描述

Go基础-007 类型描述

作者: 如逆水行舟不进则退 | 来源:发表于2020-02-23 18:34 被阅读0次

1.变量强类型

变量在声明时,需要明确指定其类型,一旦定义不可改变。
变量,仅仅可以存储对应的类型的数据!

2.静态类型和动态类型

关于变量的类型,其中声明类型称之为静态类型,而真实值类型我们称之为动态类型。
典型的数据类型变量的静态和动态类型保持一致。例如 var x int; x = 42;

// 保持一致 动静一致
var x int // x 的静态类型是 
int x = 42 // x 的动态类型是 int

注意:在一种叫做接口的数据类型上,动态类型和静态类型不一致。
优势是 在处理动态数据时,需要在运行时确定数据的真实类型。此时,需要一个机制来处理,所以使用空接口进行处理。

3.空接口,interface{},任意类型

接口,interface,本质用来定义一组操作。

空接口,没有定义任何操作的接口,该接口满足任何类型的定义。
字面量如下: interface{}

空接口的意义在于,可以定义一个变量为空接口类型,使用该变量存储任意的数据数据类型。

代码:

// x 的静态类型是 interface{} 
var x interface{}
// 赋值为 42 int 型
x = 42 
fmt.Println(x)

// 赋值 "hank" string 型 
x = "hank"
fmt.Println(x)
// 赋值 false bool 型
x = false 
fmt.Println(x) 

其中,x 变量的静态类型 interface{}空接口,而动态类型,随着其赋值而定,分别为 int, string,bool 型。

注意:空接口 interface{} 也是一种数据类型,虽然可以被赋值为 int,string 或其他类型 的数据,但是 interface{} 与其他类型不一致,是一种独立的类型。即使我们将字符串类型 赋值给了空接口类型变量,也不能与字符串类型直接做运算,
代码演示:

var x interface{}
// 赋值 "hank" string 型
x = "hank"
fmt.Println(x + " " + "GoLang")
// 报错:# command-line-arguments
// .\type.go:28:16: invalid operation: x + " GoLang" (mismatched types interface {} and string)

若需要真正的获取空接口变量中存储的特定类型的数据,需要使用类型断言或类型检测 来实现。

4.类型断言

用于断定空接口中的数据是何种类型,断定成功,会获取该类型的数据,断定失败,获
取不成功。 语法如下:

  • 数据变量 := 空接口类型变量.(T)
  • 数据变量, 断言结果 := 空接口类型变量.(T)
    其中 T 是某种特定类型。
    空接口类型变量.(Type) 才是断言的语法,支持两种返回形式,直接获取值或者同时获
    取断言结果。

代码演示:

var x interface{}
// 赋值 "hank" string 型
x = "hank"

// 断言为字符串类型,不获取断言结果,通常在可以从逻辑上确定数据类型
时使用。
sx := x.(string) 
fmt.Printf("%T\n", sx)  // string
fmt.Println(sx) // hank
var y interface{} 
y = 42

// 断言为字符串类型,需要获取断言结果,通常在不能判断是否为我们需要
的数据类型时使用。提供了错误处理 
sy, e := y.(string) 
fmt.Println(e) // false

// 当断言失败时,人为处理需要的数据 
if !e { // 断言失败
   sy = "default string" 
}
fmt.Println(sy) // default string

5.类型测试

可以通过 interface.(type) (type 就是 type 关键字,不是数据类型的意思)与 switch 结
构配合使用,完成类型检测。
代码演示:

var x interface{} 
x = 42
// x = "hank"
// x = false
switch d := x.(type) { 
case int:
  fmt.Println(d, d+42)  // 42 84
case string:
  fmt.Println(d, d + " GoLang")  // hank  hank Golang
case bool:
  fmt.Println(d, !d)  // false true
}

注意: 这种语法 和 switch 的常规语法不一致,是一种特殊的语法

6.类型转换

将通过 A 类型的数据,得到 B 类型的数据,该转换过程,称之为类型转换。 语法:
B 类型数据 = B 类型标识(A 类型数据)

代码演示:

// 类型转换
var x int = 42
var y float64 = 42.5 
fmt.Println(float64(x) + y) //  84.5

若不转换,语法检测失败,不同类型不能计算:
invalid operation: x + y (mismatched types int and float64)

典型的转换情况:

  • 数值类型间的转换,整型转为浮点型,浮点型转换整型
  • 字符串和字节切片[]byte相互转换
    代码演示:
        // 类型转换
    var x int = 42
    var y float64 = 42.5
    fmt.Println(float64(x) + y) // 84.5
    fmt.Println(x + int(y)) // 84

    var z string = "hank"
    fmt.Println([]byte(z)) //[104 97 110 107]

    var a []byte = []byte {104, 97, 110, 107,}
    fmt.Println(string(a)) // hank

除此之外的类型间的相互转换是不被允许,例如将其他类型转为布尔类型。

代码演示:

var b int = 0 
fmt.Println(bool(b))
// 报错: #command-line-arguments
// .\type.go:73:18: cannot convert b (type int) to type bool

7.类型定义

自定义的的数据类型。 可以基于内置的数据类型,构建自定义的数据类型,称之为类型定义。使用语法: type 类型标识符 类型描述字面量

最典型的情况,就是结构体类型的定义:

type Person struct {
   ID string
   Name string
   age int 
}

其中,Person 就是我们自定义的数据类型,其对应的类型描述,是后边的结构体类型 的字面量。

除了结构体,我们可以使用任意的内置类型来定义我们的自定义类型,演示:

// 类型定义
type age int
type height int
type position struct {
  x int
  y int 
}
type hobby []string

定义好的数据类型,使用的语法与内置的类型一致,演示:

type age int
var a age = 42
fmt.Println(a, a + 42) // 42 84

type hobby []string
var c hobby = hobby{"basketball", "football"} 
//亦可 :c := hobby{"basketball", "football"}

fmt.Println(c, len(c), c[1]) // [basketball football] 2 football

注意:基于某种类型定义的新类型,继承某种类型的方法集合(操作集合),age 就支持 int
型加减乘除运算,hobby 类型就支持 []string 的索引,长度等运算。但是,定义的类型与其基础类型(就是 age 和 int)是不同的两种数据类型,不能做直接运算,但是可以通过类型转换,转换为对应的类型。

var a age = 42
var b int = 1024
// fmt.Println(a, a + 42, a + b) 
// 报错 .\type.go:86:27: invalid operation: a + b (mismatched types age and int)

fmt.Println(a, a + 42, a + age(b), int(a) + b) 
// 输出:42 84 1066 1066

为了统一概念,任何数据类型都有基础类型,包括 int 和[]string,这些预定义的内置类 型或类型的字面量的基础类型是其本身。

  • age 和 int 的基础类型都是 int
  • hobby he []string 的基础类型都是 []string

其中,类型字面量包括自定义类型的字面量类型,例如,若:type ages []age,其中 ages 的基础类型就是 []age。

8.类型别名

别名,另一个名字,同一个类型的不同的名字,称之为类型别名。

语法:type 别名 = 类型 (与类型定义的差异是存在等号)

代码演示:

type age = int
var a age = 42
var b int = 1024 
fmt.Println(a, a + 42, a + b) // 42 84 1066

给类型取一个满足业务逻辑的名字,并没有增加新类型,因此不同别名但同一类型间的
数据,可以直接做运算!

内置的类型:
byte 和 rune 其实就是通过别名的方案来定义的,也是整型集团内的。

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32

9.其他功能类型

功能上的类型,不表示数据,用于实现某个特定功能。有:

  • 函数,function,定义功能模块
  • 接口,interface,用于定义操作限定
  • 信道,channel,完成goroutine间的通讯

相关文章

  • Go基础-007 类型描述

    1.变量强类型 变量在声明时,需要明确指定其类型,一旦定义不可改变。变量,仅仅可以存储对应的类型的数据! 2.静态...

  • Go学习-数据类型

    Go数据类型 Go语言将数据类型分为四类 基础类型 复合类型 引用类型 接口类型 基础类型 数字 字符串 布尔 整...

  • Go 语言程序设计(3)

    stacker.go 示例代码: stack.go 示例代码: 知识点: go 内置基础类型:布尔类型: bool...

  • 《GO语言圣经》读书笔记 第三章 基础数据类型

    Go语言将数据类型分为四类:** 基础类型、复合类型、引用类型和接口类型 ** 整型 Go语言的数值类型包括几种不...

  • golang reflect 反射包

    基础类型描述 Type Kindtype Kind uint 基础类型常量const ( Invalid K...

  • 初识Go语言-1

    Go语言学习路径 初识Go语言 Go语言环境搭建与IDE安装 Go语言基础语法 Go语言数据类型 Go语言变量和常...

  • Go语言第3天 - 常用数据类型

    以下内容部分参考自Go语言基础数据类型Go语言中的数组切片:特立独行的可变数组Go语言数据类型-数组Go标准容器之...

  • 第三章:Go语言基础数据类型

    1. Go语言数据类型 1.1 数据类型分类 Go语言数据类型大致可以分为两类基础类型,其中就包括了我们最常见的一...

  • Go语言入门指南系列之《2基础类型》

    Go 语言中的基础类型   在 Go 编程语言中,数据类型用于声明函数和属性。数据类型的出现时为了把数据分成所需要...

  • 【Golang 基础】Go 语言中的基本类型

    Go 语言中的基础类型   在 Go 编程语言中,数据类型用于声明函数和属性。数据类型的出现时为了把数据分成所需要...

网友评论

      本文标题:Go基础-007 类型描述

      本文链接:https://www.haomeiwen.com/subject/unlkqhtx.html