zoukankan      html  css  js  c++  java
  • GO语言系列之 基本数据类型和操作符

    一、文件名 & 关键字 & 标识符

    • 1.所有go源码以.go结尾

    • 2.标识符以字母或下划线开头,大小写敏感

    • 3._是特殊标识符,用来忽略结果

    • 4.保留关键字

     除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:

    append bool byte cap close complex complex64 complex128 uint16
    copy false float32 float64 imag int int8 int16 uint32
    int32 int64 iota len make new nil panic uint64
    print println real recover string true uint uint8 uintptr

    二、Go程序的基本结构

    package main
    
    import "fmt"
    
    func main() {
    	fmt.Println("hello world")
    }

     1. 任何一个代码文件隶属于一个包

     2.import 关键字,引用其他包

    import ("fmt")
    import ("os")
    通常习惯写成
    import (
    "fmt"
    "os"
    )
    

     3.golang可执行程序,package main, 并且有且只有一个main入口函数

     4.包中函数调用

      a.同一个包中函数,直接调用

      b.不同包中函数,通过包名+点+函数名进行调用

     5.包访问控制权限

      a.大写意味着这个函数/变量是可导出的

      b.小写意味着这个函数/变量是私有的,包外部不能访问

    小练习

    1. 写一个程序,对给定一个数字n,求出所有两两相加等于n的组合

    package main
    
    import "fmt"
    
    func list(n int) {
        for i := 0; i <= n; i++ {
            fmt.Printf("%d+%d=%d
    ", i, n-i, n)
        }
    }
    
    func main() {
        list(10)
    }
    
    // go build -o bin/list.exe go_dev/day2/example1/main
    练习1

    2. 一个程序包含两个包add和main,其中add包中有两个变量:Name和age。请问main包中如何访问Name和age?

    package add
    
    // 方式一
    // var Name string = "hello world"
    // var Age int = 10
    
    // 方式一
    // var Name string = "hello world"
    // var Age int = 10
    
    // 方式二
    var Name string
    var Age int
    
    func Test() {
        Name = "hello wrold"
        Age = 20
    }
    add.go
    package main
    
    import (
        "fmt"
        "go_dev/day2/example2/add"
    )
    
    func main() {
        // 方式一 直接调用
        // fmt.Println("Name=", add.Name)
        // fmt.Println("Age=", add.Age)
    
        // 方式二 先调用函数
        add.Test()
        fmt.Println("Name=", add.Name)
        fmt.Println("Age=", add.Age)
    }
    main.go

    3. 包别名的应用,开发一个程序,使用包别名来访问包中的函数?

    package main
    
    import (
        "fmt"
        a "go_dev/day2/example2/add"
    )
    
    func main() {
        // 方式一 直接调用
        // fmt.Println("Name=", add.Name)
        // fmt.Println("Age=", add.Age)
    
        // 方式二 先调用函数
        // add.Test()
        // fmt.Println("Name=", add.Name)
        // fmt.Println("Age=", add.Age)
    
        // 包的别名
        a.Test()
        fmt.Println("Name=", a.Name)
        fmt.Println("Age=", a.Age)
    }
    main.go

    4. 每个源文件都可以包含一个init函数,这个init函数自动被go运行框架调用。开发一个程序演示这个功能?

    package add
    
    // 先执行全局变量,在执行init函数, 在执行main函数
    
    // 方式一
    // var Name string = "hello world"
    // var Age int = 10
    
    // 方式二
    var Name string
    var Age int
    
    func Test() {
        Name = "hello wrold"
        Age = 20
    }
    
    func init() {
        Name = "hello wrold"
        Age = 20
    }
    add.go
    package main
    
    import (
        "fmt"
        // "go_dev/day2/example2/add"
        a "go_dev/day2/example2/add"
    )
    
    func main() {
        // 方式一 直接调用
        // fmt.Println("Name=", add.Name)
        // fmt.Println("Age=", add.Age)
    
        // 方式二 先调用函数
        // add.Test()
        // fmt.Println("Name=", add.Name)
        // fmt.Println("Age=", add.Age)
    
        // 包的别名
        // a.Test()
        // fmt.Println("Name=", a.Name)
        // fmt.Println("Age=", a.Age)
    
        // init
        fmt.Println("Name=", a.Name)
        fmt.Println("Age=", a.Age)
    }
    main.go

    5. 包的只初始化,不引用。请开发一个程序,演示这个做法

    package test
    
    import "fmt"
    
    var Name string = "hello world"
    var Age int = 1000
    
    func init() {
        fmt.Println("Name=", Name)
        fmt.Println("Age=", Age)
    
        Age = 10
        fmt.Println("Age=", Age)
        fmt.Println("this is a test....")
    }
    test.go
    package add
    
    import (
        _ "go_dev/day2/example2/test"
    )
    add.go

    三、函数声明和注释

     1.函数声明:func 函数名字(参数列表)(返回值列表){}

     2. 注释,两种注释,单行注释://和多行注释 /* */

    四、常量和变量

    1. 常量

    • (1). changliang使用const修饰,代表永远是只读的,不能修改
    • (2). const只能修饰boolean,number(int相关类型、浮点类型、complex)和string
    • (3). 语法:const identifier[type] = value,其中type可以省略
    • (4). 比较优雅的写法
    const (
      a = 0
      b = 1
      c = 2   
    )
    
    • (5). 更加专业的写法
    const (
      a = iota
      b   // 1
      c   // 2
    )

    练习

    1. 定义两个常量Man=1和Female=2,获取当前时间的秒数,如果能被Female整除,则在终端打印female,否则打印man。Second := time.Now().Unix()

    package main
    
    import (
        "fmt"
        "time"
    )
    
    const (
        Man    = 1
        Female = 2
    )
    
    func main() {
        second := time.Now().Unix()
        if second%Female == 0 {
            fmt.Println("Female")
        } else {
            fmt.Println("Man")
        }
    }
    main.go

    2、变量

     (1). 语法:var identifier type

    例1

    var a int
    var b string
    var c bool
    var d int = 8
    var e string = "hello world"

     例2

    var (
    a int   // 默认为0
    b string  // 默认为“”
    c bool   // 默认为false
    d  = 8
    e  = "hello world"
    )

     练习

    1. 写一个程序获取当前运行的操作系统名称和PATH环境环境变量的值,并打印在终端。

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func get_os() {
        go_os := os.Getenv("GOOS")
        fmt.Printf("the operaing system is: %s
    ", go_os)
        path := os.Getenv("PATH")
        fmt.Printf("Path is: %s
    ", path)
    }
    
    func main() {
        get_os()
    }
    main.go

    变量的作用域

    • 1.  在函数内部声明的变量叫做局部变量,生命周期仅限于函数内部。

    • 2. 在函数外部声明的变量叫做全局变量,生命周期作用于整个包,如果是大写的,则作用于整个程序。

    五、数据类型和操作符

    1. 值类型和引用类型

    • 值类型:变量直接存储值,内存通常在栈中分配

    • 引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配。通过GC回收。

    值类型:基本数据类型int、float、bool、string以及数组和struct

    引用类型:指针、slice、map、chan等都是引用类型。

    练习:

    • 写一个程序用来打印值类型和引用类型变量到终端,并观察输出结果
    package main
    
    import "fmt"
    
    func main() {
    	a := 5
    	b := make(chan int, 1)
    
    	fmt.Println("a=", a)
    	fmt.Println("b=", b)
    
    }
    
    输出
    // a= 5
    // b= 0xc00003a070
    • 写一个程序,交换两个整数的值。比如: a=3; b=4; 交换之后:a=4;b=3
    package main
    
    import "fmt"
    
    var n int = 100
    
    /*
    赋值语句只能在函数中, 以下情况都会报错
    var a int
    a = 100
    或者
    a := 100
    */
    
    func swap(a int, b int) {
        tmp := a
        a = b
        b = tmp
    }
    
    func swap1(a int, b int) (int, int) {
        return b, a
    }
    
    func swap2(a *int, b *int) {
        // 改变的是地址指向的那片内存的值
        tmp := *a
        *a = *b
        *b = tmp
    }
    
    func test() {
        // 类型转换
        var a int8 = 100
        var b int16 = int16(a) //  赋值必须类型相同
    
        fmt.Printf("a=%d, b=%d", a, b)
    }
    
    func main() {
        first := 10
        second := 20
    
        // 方式一
        swap(first, second) // copy的是first和second的变量值
    
        fmt.Println("first=", first)
        fmt.Println("second=", second)
    
        // 方式二
        a, b := swap1(first, second)
    
        fmt.Println("a=", a)
        fmt.Println("b=", b)
    
        // 方式三
        c, d := second, first
    
        fmt.Println("c=", c)
        fmt.Println("d=", d)
    
        // 方式四
        swap2(&first, &second) // copy的是first和second的地址
    
        fmt.Println("first=", first)
        fmt.Println("second=", second)
    
        test()
    
    }
    交换a和b的四种方式

    2. 数据类型和操作符

    • 基础数据类型

     (1) bool类型,只能存true或false

     (2) 相关操作符,!、&&、||

     (3) 数字类型,主要有int、int8、int16、int32、int64、uint8、uint16、uint32、uint64、float32、float64

     (4) 类型转换,type(variable),比如:var a int=8;  var b int32=int32(a)

     (5) 字符类型:var a byte = 'c'

     (6) 字符串类型:var str string = "hello world"

    注:字符串表示两种方式:

      1)“”    双引号:支持转义字符,如 , , %%等等

      2)``   (反引号): 不支持转义字符,内容按原样输出

    • 操作符

    (1) 逻辑操作符:=、!=、<、<=、>和>=

    (2) 数学操作复:+、-、*、/ 等等

    练习

    • 使用math/rand生成10个随机整数,10个小于100的随机整数以及10个随机浮点数?
    package main
    
    import (
        "fmt"
        "math/rand"
        "time"
    )
    
    func init() {
        rand.Seed(time.Now().Unix())
    }
    
    func main() {
    
        for i := 0; i < 10; i++ {
            a := rand.Int()
            fmt.Println(a)
        }
    
        for i := 0; i < 10; i++ {
            a := rand.Intn(100)
            fmt.Println(a)
        }
    
        for i := 0; i < 10; i++ {
            a := rand.Float32()
            fmt.Println(a)
        }
    }
    main.go
    • 字符串两种表示方式
    package main
    
    import "fmt"
    
    func main() {
        var str = "hello world
    "
        var str1 = `
            床前明月光,
            疑是地上霜,
            举头望明月,
            低头思故乡。
        `
        var b byte = 'c'
    
        fmt.Println(str)
        fmt.Println(str1)
        fmt.Println(b)
        fmt.Printf("%c
    ", b)
    }
    
    输出:
    hello world
    
    
            床前明月光,
            疑是地上霜,
            举头望明月,
            低头思故乡。
        
    99
    c
    字符串两种表示方式
    • 字符串逆转
    package main
    
    import "fmt"
    
    func reverse(str string) string {
        var result string
        strlen := len(str)
        for i := 0; i < strlen; i++ {
            result = result + fmt.Sprintf("%c", str[strlen-i-1])
        }
        return result
    }
    
    func reverse1(str string) string {
        var result []byte
        tmp := []byte(str)
        length := len(str)
        for i := 0; i < length; i++ {
            result = append(result, tmp[length-i-1])
        }
        return string(result)
    }
    
    func main() {
        str1 := "hello"
        str2 := "world"
    
        // str3 := str1 + " " + str2
        str3 := fmt.Sprintf("%s %s", str1, str2)
        n := len(str3)
    
        fmt.Println(str3)
        fmt.Printf("len(str3)=%d
    ", n)
    
        substr := str3[0:5]
        fmt.Println(substr)
    
        substr = str3[6:]
        fmt.Println(substr)
    
        result := reverse(str3)
        fmt.Println(result)
    
        result1 := reverse1(str3)
        fmt.Println(result1)
    }
    main.go
    • 复杂数据类型
    结构体 struct
    接口 interface
    数组 [数组长度]值类型{值1,值2}
    切片 slice  []值类型{值1,值2}
    map  [key类型]值类型{key:值}
    指针 *
    函数 func
    管道 chan
    • 取值范围
    int8
    -128到127
    
    uint8
    0到255
    
    int16
    -32768到32767
    
    uint16
    0到65535
    
    int32
    -2147483648到2147483647
    
    uint32
    0到4294967295
    
    int64
    -9223372036854775808到9223372036854775807
    
    uint64
    0到18446744073709551615
    取值范围
    • 数据格式转换

    package main
    
    import (
        "encoding/json"
        "fmt"
        "reflect"
        "strconv"
    )
    
    type User struct {
        Id   int    `json:"id"`
        Name string `json:"name"`
    }
    
    func main() {
        //string到int
        n10, _ := strconv.Atoi("12")
        fmt.Println(reflect.TypeOf(n10))
        // string到int64
        n64, _ := strconv.ParseInt("12", 10, 64)
        fmt.Println(reflect.TypeOf(n64))
        // string to float32、float64
        f_32, _ := strconv.ParseFloat("3.1415", 32)
        f_64, _ := strconv.ParseFloat("3.1415", 64)
        fmt.Printf("%T
    ", f_32)  // float64
        fmt.Printf("%T
    ", f_64)
    
        // int到string
        s1 := strconv.Itoa(11)
        fmt.Println(reflect.TypeOf(s1))
        // int64到string
        s2 := strconv.FormatInt(11,10)
        fmt.Println(reflect.TypeOf(s2))
        // float32/64 to string
        s3 := strconv.FormatFloat(3.1415, 'E', -1, 32)
        s4 := strconv.FormatFloat(3.1415, 'E', -1, 64)
        fmt.Println(reflect.TypeOf(s3))
        fmt.Println(reflect.TypeOf(s4))
    
        // int和int64
        n_10_64 := int64(11)
        fmt.Println(reflect.TypeOf(n_10_64))
        // int64 to int
        n_64_10 := int(n_10_64)
        fmt.Println(reflect.TypeOf(n_64_10))
    
        s := `{"id": 1, "name": "wxnacy"}`
    
        // 将字符串反解析为结构体
        var user User
        _ = json.Unmarshal([]byte(s), &user)
        fmt.Println(user) // {1 wxnacy}
    
        // 将字符串反解析为字典
        var d map[string]interface{}
        _ = json.Unmarshal([]byte(s), &d)
        fmt.Println(d) // map[id:1 name:wxnacy]
    
        // 将字符串反解析为数组
        s = `[1, 2, 3, 4]`
        var a []int
        _ = json.Unmarshal([]byte(s), &a)
        fmt.Println(a) // [1 2 3 4]
    
        // 将结构体解析为字符串
        str_user, _ := json.Marshal(user)
        fmt.Println(string(str_user))// {"id":1,"name":"wxnacy"}
        // 数组解析为字符串
        str_a, _ := json.Marshal(a)
        fmt.Println(string(str_a)) // [1,2,3,4] <nil>
        // map解析为字符串
        str_d, _ := json.Marshal(d)
        fmt.Println(string(str_d)) // {"id":1,"name":"wxnacy"} <nil>
    }
    各种数据类型格式转换

    六、栈和堆

    • 栈是在栈内存中分配的,公用的,性能最高, 堆是在系统内存中分配的

    • 基本数据类型是在栈中存储的 引用数据类型是在堆中存储的

    函数传参:做了一个拷贝,如果参数为变量值,则函数内部对变量做的操作不会影响实际变量的值。若传的参数为地址,则对地址指向变量的操作会影响实际变量的值。

    package main
    
    import "fmt"
    
    func modify(a int) {
    	a = 10
    	return
    }
    
    func modify1(a *int) {
    	*a = 10
    }
    
    func main() {
    	a := 5
    	b := make(chan int, 1)
    
    	fmt.Println("a=", a)
    	fmt.Println("b=", b)
    
    	modify(a) // 做了一个拷贝, 不影响原来的值
    	fmt.Println("a=", a)
    
    	modify1(&a) // 参数传了一个地址,对其指向的变量值进行操作会影响其地址指向的变量值
    	fmt.Println("a=", a)
    }
    
    // 栈是在栈内存中分配的,公用的,性能最高, 堆是在系统内存中分配的
    // 基本数据类型是在栈中存储的 引用数据类型是在堆中存储的
    
    /*
    a= 5
    b= 0xc00008c000
    a= 5
    a= 10
    */

    练习作业

    • 1. 判断 101-200 之间有多少个素数,并输出所有素数。注:定义:为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数
    • 2. 打印出100-999中所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153 是一个“水仙花数”,因为 153=1 的三次方+5 的三次方+3 的三次方。
    • 3. 对于一个数n,求n的阶乘之和,即: 1! + 2! + 3!+…n!

    参考

    // 判断 101-200 之间有多少个素数,并输出所有素数。
    package main
    
    import (
        "fmt"
        "math"
    )
    
    func isPrime(n int) bool {
        sqrt_n := int(math.Sqrt(float64(n))) + 1
        for i := 2; i < sqrt_n; i++ {
            if n%i == 0 {
                return false
            }
        }
        return true
    }
    
    func main() {
        var n int
        var m int
    
        fmt.Printf("请输入两个数字:")
        fmt.Scanf("%d%d", &n, &m)
    
        for i := n; i < m; i++ {
            if isPrime(i) == true {
                fmt.Printf("%d
    ", i)
            }
        }
    }
    作业一
    /*
     打印出100-999中所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。
    例如:153 是一个“水仙花数”,因为 153=1 的三次方+5 的三次方+3 的三次方。
    */
    
    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func isShuixianhua(n int) bool {
        var i, j, k int
        i = n % 10
        j = (n / 10) % 10
        k = (n / 100) % 10
        sum := i*i*i + j*j*j + k*k*k
        return sum == n
    }
    
    func isShuixianhua2(n int) bool {
        var result = 0
        str := strconv.Itoa(n)
        for i := 0; i < len(str); i++ {
            num := int(str[i] - '0')
            result += (num * num * num)
        }
        number, err := strconv.Atoi(str)
        if err != nil {
            fmt.Printf("can not convert %s to int
    ", str)
        }
        if result == number {
            return true
        }
        return false
    }
    
    func main() {
        var n int
        var m int
    
        fmt.Printf("请输入两个数字:")
        fmt.Scanf("%d,%d", &n, &m)
    
        for i := n; i <= m; i++ {
            if isShuixianhua(i) == true {
                fmt.Println(i)
            }
        }
    }
    作业二
    // 对于一个数n,求n的阶乘之和,即: 1! + 2! + 3!+…n!
    
    package main
    
    import "fmt"
    
    func sum(n int) uint64 {
        var s uint64 = 1
        var sum uint64 = 0
        for i := 1; i <= n; i++ {
            s = s * uint64(i)
            fmt.Printf("%d!=%d
    ", i, s)
            sum += s
        }
        return sum
    }
    
    func main() {
        var n int
    
        fmt.Printf("请输入一个数字:")
        fmt.Scanf("%d", &n)
    
        s := sum(n)
        fmt.Println(s)
    }
    作业三
  • 相关阅读:
    教程:如何手动安装Xamarin与Xamarin for VisualStudio
    安装matplotlib
    pycharm中文专业版安装使用
    在win7下安装PowerShell 5.0遇到的坑
    1997-2017
    系统界面截图
    组态与非组态结合的LT
    opencv mat转qimage
    QTableWidget 样式文件
    hiredis window 源码编译
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/10650909.html
Copyright © 2011-2022 走看看