GO语言系列(二)- 基本数据类型和操作符

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

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

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

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

  • 4.保留关键字

二、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\n", 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\n", go_os)
    path := os.Getenv("PATH")
    fmt.Printf("Path is: %s\n", path)
}

func main() {
    get_os()
}
main.go

变量的作用域

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

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

五、数据类型和操作符

1. 值类型和引用类型

  • 值类型:基本数据类型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\n"
    var str1 = `
        床前明月光,
        疑是地上霜,
        举头望明月,
        低头思故乡。
    `
    var b byte = 'c'

    fmt.Println(str)
    fmt.Println(str1)
    fmt.Println(b)
    fmt.Printf("%c\n", 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", 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

六、栈和堆

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

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

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

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
*/

  

猜你喜欢

转载自www.cnblogs.com/zhangyafei/p/10650909.html
今日推荐