Go语言的数据类型有哪些?
1.基本的数据类型:
常量、整型、浮点型、复数、字符串、布尔型
2.复合数据类型:
数组、切片、map、结构体、json……
今天想记录的
因为基本的数据类型各种语言基本上语法,用法都差不多,所以重点记录一下复合数据类型的用法。
正文
1.数组
数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成,而且数组的长度是固定的。因为数组不那么灵活,所以一般使用切片,这里只简单介绍一下数组的几种基本用法。
package main
import (
"fmt"
)
func main() {
//首先是简单的数组创建
//1.输入数组大小的创建
var a [3]int
var b [3]int=[3]int{1,2,3}
fmt.Println(a)
fmt.Println(b)
//2.不输入数组大小,只输入数组元素的创建
q := [...]int{1, 2, 3}
fmt.Println(q)
}
这里还要介绍几个容易弄混的函数iota,Atoi,Itoa
首先是iota,这是一个枚举类型,主要作用可以想象成主动实现count+=1
package main
import (
"fmt"
)
type week int
const (
Sunday week = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func main() {
fmt.Println(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
}
这样一周七天就变成了对应的数值,使用switch也可以很好的知道输入的对应是哪一天。
Itoa,Atoi这两个刚好是相反的,前者用来把数值转化为字符串,后者把字符串转为数值
package main
import (
"strconv"
)
func main() {
i, err := strconv.Atoi("12345")
if err != nil {
panic(err)
}
i += 3
println(i)
s := strconv.Itoa(12345)
s += "3"
println(s)
}
2.切片
其实切片的用法和python中list的切片是大致相同的,所以主要讲讲append函数
package main
import (
"fmt"
)
func main() {
var runes []rune
for _, r := range "Hello,World" {
runes = append(runes, r)
}
fmt.Printf("%q\n", runes)
}
package main
import "fmt"
func main() {
var y, z []int
for i := 0; i < 10; i++ {
z = appendInt(y, i)
fmt.Printf("%d cap=%d\t%v\n", i, cap(z), z)
y = z
}
var k []int
k = appendInt(k, 3, 5)
k = appendInt(k, k...)
fmt.Println(k)
var w []int
w = append(w, 3, 5)
w = append(w, w...)
fmt.Println(w)
}
//简单实现一个append
func appendInt(x []int, y ...int) []int {
var z []int
zlen := len(x) + len(y)
if zlen <= cap(x) {
z = x[:zlen]
} else {
zcap := zlen
if zcap < 2*len(x) {
zcap = 2 * len(x)
}
z = make([]int, zlen, zcap)
copy(z, x)
}
copy(z[len(x):], y)
return z
}
3.Map
Map其实可以理解为键值对,类似于python中的字典(拿python的类型举例完全是因为python简单很好理解)
package main
import (
"fmt"
"sort"
)
func main() {
ages := make(map[string]int)
ages["1"] = 22
ages["2"] = 21
ages["3"] = 23
for name, age := range ages {
fmt.Printf("%s:%d\n", name, age)
}
names := make([]string, 0, len(ages))
for name := range ages {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
fmt.Printf("%s\t%d\n", name, ages[name])
}
//删除操作
//delete(ages, "1")
//fmt.Println(ages)
age, ok := ages["1"]
if !ok {
fmt.Printf("找不到该值")
} else {
fmt.Printf("找到了该人的年龄,age=%d", age)
}
}
4.结构体
和c语言基本一样,但是结构体的嵌套(组合)很好的实现了oop中的继承
package main
import (
"fmt"
"time"
)
type Employee struct {
ID int
Name, Address string
DoB time.Time
Position string
Salary int
ManagerID int
}
type address struct {
hostname string
port int
}
type Point struct {
X, Y int
}
type Circle struct {
Point
Radius int
}
type Wheel struct {
Circle
Spokes int
}
func main() {
var dilbert Employee
var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"
dilbert.Salary += 5000 //初始值都是0
position := &dilbert.Position
*position = "Senior " + *position
fmt.Printf("%s,%d\n", dilbert.Position, dilbert.Salary)
fmt.Printf("%s", employeeOfTheMonth.Position)
//结构体也可以作为map的key
hits := make(map[address]int)
hits[address{"golang.org", 443}]++
fmt.Println(hits)
var w Wheel
w.X = 8 // equivalent to w.Circle.Point.X = 8
w.Y = 8 // equivalent to w.Circle.Point.Y = 8
w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20
fmt.Printf("%#v\n", w)
//用下面这两种字面值也是可以的,结果是一样的
//w = Wheel{Circle{Point{8, 8}, 5}, 20}
//
//w = Wheel{
// Circle: Circle{
// Point: Point{X: 8, Y: 8},
// Radius: 5,
// },
// Spokes: 20, // NOTE: trailing comma necessary here (and at Radius)
//}
//
//fmt.Printf("%#v\n", w)
Output:
Wheel{Circle:Circle{Point:Point{X:8, Y:8}, Radius:5}, Spokes:20}
//
//w.X = 42
//
//fmt.Printf("%#v\n", w)
}
package main
import "fmt"
/*
继承
一个结构体嵌到另一个结构体,称作组合
匿名和组合的区别
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现继承
如果一个struct嵌套了另一个【有名】的结构体,那么这个模式叫做组合
如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现多重继承
*/
type Car struct {
weight int
name string
}
func (p *Car) Run() {
fmt.Println("running")
}
type Bike struct {
Car
lunzi int
}
type Train struct {
Car
}
func (p *Train) String() string {
str := fmt.Sprintf("name=[%s] weight=[%d]", p.name, p.weight)
return str
}
func main() {
var a Bike
a.weight = 100
a.name = "bike"
a.lunzi = 2
fmt.Println(a)
a.Run()
var b Train
b.weight = 100
b.name = "train"
b.Run()
fmt.Printf("%s", &b)
}
5.JSON
将一个Go语言中的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成。这种紧凑的表示形式虽然包含了全部的信息,但是很难阅读。为了生成便于阅读的格式,另一个json.MarshalIndent函数将产生整齐缩进的输出。该函数有两个额外的字符串参数用于表示每一行输出的前缀和每一个层级的缩进。
package main
import (
"encoding/json"
"fmt"
"log"
)
type Movie struct {
Title string
Year int `json:"released"`
Color bool `json:"color,omitempty"`
Actors []string
}
var movies = []Movie{
{Title: "Casablanca", Year: 1942, Color: false,
Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},
{Title: "Cool Hand Luke", Year: 1967, Color: true,
Actors: []string{"Paul Newman"}},
{Title: "Bullitt", Year: 1968, Color: true,
Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},
// ...
}
func main() {
data, err := json.Marshal(movies)
if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n", data)
data2, err := json.MarshalIndent(movies, "", " ")
if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n", data2)
}
总结
主要常用的复杂数据类型基本都记录了一下,虽然都只是简单的说说,但是看代码中的那些基本用法也能对入门go有所帮助。