go三:变量、数据类型及其转换

一、变量

变量的功能是存储数据,通过变量名访问。

变量的本质,是计算机分配的一块内存。

数据类型:

int、string、[]float、func() bool、struct

声明变量:

  1. 未初始化的标准格式:var 变量名 变量类型
  2. 未初始化的批量格式:var (变量名 变量类型;................) 
  3. 未初始化的变量的默认值:int、float的默认值为0,string的默认值为空字符串,布尔型默认值为false,函数和指针的默认值为nil,切片[]的默认值为[]
  4. 初始化变量的标准格式:var 变量名 变量类型 = 表达式
  5. 初始化变量的编译器自动推断类型格式:var 变量名 = 表达式
  6. 初始化变量的简短声明格式

 匿名变量:使用"_"下划线替换,不占用命令空间,不会分配内存

二、常量

 常量,是恒定不变的值,在程序运行时,不会被修改。

常量,只可以是布尔型、数字型(整数型、浮点型、复数)和字符串型

常量的声明:const 常量名 [类型] = 值

多个常量的声明:const 常量名,常量名 = value1, value 2

常量组的声明:const (常量名=value; 常量名=value),常量组的第一个常量必须赋值。

常量的类型,可以不写,编译器可以根据变量的值来自动推断其类型。

常量定义后未被使用,不会在编译时出错。

func main() {
    const (
        a = 10
        b  //在常量组中,如果常量未指定类型和初始值,则与上一行非空常量的类型和值相同
        c
    )
    fmt.Println(a, b, c)
}
打印结果:10 10 10
type Man struct {
    age, height int
}
func main() {
    const NAME string = "jerry"
    //NAME = "alen" //出错,常量不可以修改
    //man := Man{30, 170}
    //const PERSON  = man //struct类型的数据,不可以作为常量
    const (
        X = "a"
        Y
        A = 10
        B
        C
    )
    fmt.Println(X, Y, A, B, C)  //打印结果:a a 10 10 10
}

 

iota,是一个特殊的常量值,是一个系统定义的可以被编译器修改的常量值。

iota,只能出现在常量中。

iota,每出现一个const关键字,被重置为0,然后每出现一个常量,iota自动加1,即iota是常量组中常量的计数器。

 

三、数据类型

基本数据类型:整型、浮点型、布尔型、字符串、字符(byte、rune)

复合数据类型:指针pointer、数组array、切片slice、映射map、函数function、结构体stuct、通道channel

 

1.整型分两大类:

按长度分:int8,int16,int32,int64,int。

无符号整型:uint8,uint16,uint32,uint64,uint。uint8就是byte型,2的8次方(0到255);uint32,2的32次方....

其它数字类型:byte类似uint8,rune类似int32,uint为32或64位,int与uint一样大,uintptr无符号整型用于存放一个指针

4.字符串:单行使用双引号,多行使用反引号。串转义符\:

  • \r 回车符,返回行首
  • \n 换行符,直接跳到下一行的同列位置
  • \t 制表符
  • \‘ 单引号,\" 双引号, \\ 反斜杠

5.字符:字符串中的每一个元素叫做字符,定义字符时使用单引号

字符有两种类型:byte型、rune型。

byte型,其实就是uint8的别名,代表了一个ASCII码的一个字符。

rune型,其实就是int32的别名,代表了一个UTF-8字符。当需要处理中文等unicode字符集时,需要用到rune类型。

 

 四、数组

没有初始值的数组的定义: var  数组名字 [数组元素个数] 数据类型

有初始值的数组的定义: var  数组名字 [数组元素个数] 数据类型 =  [数组元素个数] 数据类型 {元素1,元素2.........}

使用自动推导的方式定义数组: 数组名字 :=  [数组元素个数] 数据类型 {元素1,元素2.........} 

数组元素的个数,可以使用“...”代替

数组名[下标]=值

二维数组示例:

package main

import "fmt"

func main() {
    var arr [3][4]int
    arr[1][2] =3
    arr[2][1]=4
    fmt.Println(arr)
    for i:=0;i<len(arr);i++ {
        for j:=0;j<len(arr[0]);j++{
            fmt.Println(arr[i][j])
        }
    }
}

 

五、切片

没有初始化的切片的定义:var 切片名 []数据类型

有初始化的切片的定义:var 切片名 []数据类型 =  []数据类型{元素,元素..............}

切片的定义(自动推导类型): 切片名 := make([]数据类型,切片长度)

  • s :=[] int {1,2,3 } 
    直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3
  • s := arr[:] 
    初始化切片s,是数组arr的引用
  • s := arr[startIndex:endIndex] 
    将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
  • s := arr[startIndex:] 
    缺省endIndex时将表示一直到arr的最后一个元素
  • s := arr[:endIndex] 
    缺省startIndex时将表示从arr的第一个元素开始
  • s1 := s[startIndex:endIndex] 
    通过切片s初始化切片s1
  • s :=make([]int,len,cap) 
    通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片 

slice可以从一个数组或一个已经存在的slice中再次声明。slice通过array[i:j]来获取,其中i是数组的开始位置,j是结束位置,但不包含array[j],它的长度是j-i

使用下标操作时,不能超过切片长度。如果超过切片长度,要追加无素,使用appen(切片,元素)

切换的copy: copy(目标切片,源切片),要注意目标切片必须有足够的容量,copy后两个切片是两个独立的内存空间。

示例:用户输入3位数,与系统随机生成的3位比较,直到相同退出程序

 六、Map字典

map中的key、value没有顺序,是随机存储的。

map没有容量限制。

map定义:

  • var定义的map: var 字典名字 map [key的数据类型]值的数据类型,容量    ---这种方式定义,一定要定义容量
  • 推导定义: 字典名字 := make(map[key的数据类型]值的数据类型,容量 {key:value, key:value })   ---数据部分,现在可以不定义 
package main
import "fmt"
func main() {
   name := make(map[int]string, 1)
   //map中的key,不是下标,只能是基本数据类型
   name[1] = "张三"
   name[5] = "李四"
   fmt.Println(name, len(name))
   for k, v := range name {
      fmt.Println(k, v)
   }

   m := make(map[string]int, 1)
   m["中国"] = 1
   m["北京"] = 2
   fmt.Println(m)
}
package main
import "fmt"
func main() {
	var arr [20]byte
	for i := 0; i < len(arr); i++ {
		fmt.Scanf("%c", &arr[i])
	}

	m := make(map[byte]int)
	for i := 0; i < len(arr); i++ {
		m[arr[i]]++
	}
	for k, v := range m {
		fmt.Printf("%c:  %d\n", k, v)
	}
}

七、结构体 

结构体赋值,不改变原变量的值。

定义结构体:type 结构体名称 struct {结构体内容}

定义结构体变量

示例:

package main

import "fmt"

//在函数外部定义结构体
type Student struct {
    id   int
    name string
    sex  string
    age  int
    addr string
}
//定义结构体变量方式一:
func main0() {
    //通过结构体名,定义结构体变量
    var s Student
    //结构体变量名.成员名
    s.id = 100
    s.name = "jerry"
    s.sex = ""
    s.age = 28
    s.addr = "地址abc"
    fmt.Println(s)  //{100 jerry 男 28 地址abc}
}
//定义结构体变量方式二:
func main2()  {
    var s Student = Student{101, "jason", "", 30, "山西"}
    fmt.Println(s.id, s.name, s)  //101 jason {101 jason 男 30 山西}
}
//定义结构体变量方式三:
func main()  {
    s := Student{age: 30, id:22, name:"bob", addr:"广东", sex:""}
    fmt.Println(s)  //{22 bob 男 30 广东}
}

 结构体数组,是数组

package main

import "fmt"

type student struct {
    id    int
    name  string
    sex   string
    age   int
    score int
    addr  string
}

func main() {
    //定义结构体数组: var 结构体数组名 [元素个数]结构体类型
    var arr [2]student
    arr[0].id = 1
    arr[1].name = "fanny"
    fmt.Println(len(arr))  //2
    for i:=0;i<len(arr);i++{
        fmt.Scan(&arr[i].id, &arr[i].name, &arr[i].sex, &arr[i].age, &arr[i].score, &arr[i].addr)
    }
    for i:=0;i<len(arr);i++ {
        fmt.Println(arr[i])
    }
}
2
1 孙尚香 女 16 88 江东
2 jerry 男 23 90 中华
{1 孙尚香 女 16 88 江东}
{2 jerry 男 23 90 中华}
    //结构体数组排序
    for i:=0;i<len(arr)-1;i++{
        for j:=0;j<len(arr)-1-i;j++ {
            //比较条件
            if arr[j].age > arr[j+1].age {
                arr[j], arr[j+1] = arr[j+1], arr[j]
            }
        }
    }

使用自动推导定义结构体数组

    arr := [3]student{{101, "alen", "", 23, 99, "江西"},
        {102, "candy", "", 23, 99, "江西"}
    }
    for i, v := range arr {
        fmt.Println(i, v)
    }

结构体切片,是切片

    //定义结构体切片
    arr := []student{{101, "alen", "", 23, 99, "江西"},
        {102, "candy", "", 23, 99, "江西"}
    }
    for i, v := range arr {
        fmt.Println(i, v)
    }
    //在切片中添加数据
    arr = append(arr, student{103, "sunny", "", 23, 99, "江西"})
    

结构体作为map中的值:

package main
import "fmt"
type stu struct {
   name  string
   age   int
   score int
}
func main() {
   //定义map,值为结构体
   m := make(map[int]stu)
   m[101] = stu{"andy", 23, 88}
   m[102] = stu{"mark", 89, 23}
   for k, v := range m {
      fmt.Println(k, v)
   }

   //定义map,值为结构体切片
   mm := make(map[int][]stu)
   mm[201] = append(mm[201], stu{"james",34, 78}, stu{"james",34, 78})
   mm[201] = append(mm[201], stu{"yello",20, 78})
   for k, v :=range mm{
      fmt.Printf("%T\n", v)
      for idex, data :=range v {
         fmt.Println("key: ", k, "index: ", idex, "value: ", data)
      }
   }
}

 

101 {andy 23 88}
102 {mark 89 23}
[]main.stu
key: 201 index: 0 value: {james 34 78}
key: 201 index: 1 value: {james 34 78}
key: 201 index: 2 value: {yello 20 78}
package main

import "fmt"

//定义结构体存储3名学生的三门成绩,求出每个学生的总成线和平均成线
type score struct {
    id int
    name string
    score [3]int //数组,作为结构体的成员
}
func main() {
    arr := []score{score{101,"小明", [3]int{100,90,56}},
    score{102, "小红", [3]int{88, 22,55}},
    score{103, "强哥", [3]int{56, 78, 99}}}
    //3名学生
    for i:=0;i<len(arr);i++{
        //三门成绩
        sum := 0
        for j:=0;j<len(arr[i].score);j++{
            sum += arr[i].score[j]
        }
        fmt.Printf("第%d名学生总成绩为: %d, 平均成绩为: %d\n", i+1, sum, sum/3)
    }
}

 

八、数据类型转换

func main() {
    c := 90
    e := 80.9
    //avg := (c + e)/2  //错误
    avg := (c + int(e))/2
    fmt.Println(avg)
    avg2 := (float64(c) + e)/2
    fmt.Println(avg2)
    //str := "jerry"
    //int(str)   //字符串不能转换为int类型
    cc := string(c)
    fmt.Println(cc)  //int可以转string类型
    x := 'Z'
    result := string(x)
    fmt.Println(result)  //字符可以转换成字符串
    y := ''
    result2 := string(y)
    fmt.Println(result2)
}
85
85.45
Z
Z
一

 

posted on 2018-03-27 13:21  myworldworld  阅读(212)  评论(0)    收藏  举报

导航