Go 基础入门

1. 变量

Go 语言是静态类型语言,由于编译时,编译器会检查变量的类型,所以要求所有的变量都要有明确的类型

变量在使用前,需要先声明。声明类型,就约定了你这个变量只能赋该类型的值。

1.1 变量声明

格式:var 变量名 类型 = 值

声明方式大概有四种,若声明时没有初始化,那么其默认值为该数据类型的 0 值,比如: string 类型就初始化为空字符串,int 类型就初始化为0,float 就初始化为 0.0,bool 类型就初始化为 false,指针类型就初始化为 nil

1、一行声明一个变量,并初始化值

var name string = "变量"

2、一次声明多个变量

var (
		age int
		gender string
	)

3、声明和初始化一个变量

使用 :=(让编译器自动根据右侧的值推测出左侧的变量数据类型),这种方法只能用于函数内部

name := "Go 变量"

// 等同
var name string = "Go 变量"

4、声明和初始化多个变量

name, age := "rose", 18

// 可以用来做变量交换
var a int = 100
var b int = 200
b, a = a, b

1.2 全局变量和局部变量

根据变量位置可将变量划分为全局变量和全局变量,Go 变量有作用域之分,每个大括号就是一个作用域,每个作用域都可以有相应的局部变量。

全局变量

全局可使用

package main

import "fmt"

// 声明全局变量
var country = "中国"

func main() {
    fmt.Println(country)
    country = "China"
    fmt.Println(country)
}

输出:

中国
China

注意:全局变量首字母小写,只能用于当前包中,大写可用于其他包文件,即外部可使用

局部变量

仅对应作用域可使用

package main

import "fmt"

func main() {
    // 声明局部变量,在当前函数中使用
    var country = "China"
    fmt.Println(country)

    if true {
        // 声明局部变量,仅在 if 中使用
        var age = 18
        fmt.Println(age)
        fmt.Println(country)
    }

    // age 不能在 if 作用域外使用
    // fmt.Println(age)

}

输出:

China
18
China

country 可在当前函数作用域中使用,但 age 不能在 if 作用域外使用。

1.3 指针变量

变量分为两种:

  • 普通变量:存储的为数据本身
  • 指针变量:存储的为数据/内存地址

指针变量声明可以使用 new 函数,也可以使用 &普通变量

package main

import "fmt"

func main() {
	// 指针变量,方法一
	var name string = "rose"
	var ptr = &name		// & 后面接变量名,表示取出该变量的内存地址

	fmt.Println(name)	// rose
	fmt.Println(ptr)	// 0xc00005e270
	
	// 指针变量,方法二 new 函数
	ptr2 := new(int)
	fmt.Println(ptr2)	// 0xc0000a6090
	fmt.Println(*ptr2)	// * 指针变量名,表示从内存中取出值、0
}

使用表达式 new(Type) 将创建一个Type类型的匿名变量,初始化为Type类型的零值,然后返回变量地址,返回的指针类型为*Type

1.4 匿名变量

常量和变量都只能声明一次,声明多次就会编译报错,匿名变量除外,它有如下优点:

  • 不分配内存,不占用内存空间
  • 不需要你为命名无用的变量名而纠结
  • 多次声明不会有任何问题

一般可以用来接收必须接收,但又用不到的值:

func GetData() (int, int) {
    return 100, 200
}
func main(){
    a, _ := GetData()
    _, b := GetData()
    fmt.Println(a, b)
}

2. 常量

常量即不可被修改的变量,支持的类型:数字型(整型、浮点型和复数)、字符串型、布尔型,如:

// 声明变量
var name = "rose"

// 声明常量
var age = 18
const age1 = 18

2.1 因式分解

const (
    v1 = 123  
    v2 = 456
    v3 = 789
    v4 = 101112
)

2.2 iota

特殊变量,可以认为是一个可修改的常量,在 const 关键字出现时被重置为 0 (const 内部的第一行之前),const 每新增一行,常量声明将使 iota 计数一次,可理解为 const 语句块中的行索引。

const (
    v1 = iota
    v2 = iota
    v3 = iota
)

v1 = 0v2、v3 分别为 1、2,可简写如下:

const (
    v1 = iota
    v2
    v3
)

示例一

package main

import "fmt"


func main() {
    const (
        v1 = iota + 2
        v2
        v3
    )
    fmt.Println(v1, v2, v3)

    const (
        v4 = iota + 2
        _
        v5
        v6
    )
    fmt.Println(v4, v5, v6)
}

输出:

2 3 4
2 4 5

示例二

package main

import "fmt"


func main() {
    const (
        i=1<<iota
        j=3<<iota
        k
        l
    )
    fmt.Println(i, j, k, l)
}

// 输出:1、6、12.24
  • <<:表示左移
  • iota 初始为 0,i 左移 0 位,值不变仍为 1
  • j 左移 1 位,变为二进制 110,即 6
  • k 左移 2 为,变为二进制:1100,即 12
  • l 左移 3 为,变为二进制:11000,即 24

注意:<<n==*(2^n)

3. 输入

接收输入的有三个函数,分别为:

  • fmt.Scan:从标准输入扫描用户输入的数据,将以空白符分隔的数据分别存入指定的函数
  • fmt.Scanln:遇到换行时才停止扫描,最后一个数据后面必须有换行或者到达结束位置
  • fmt.Scanf:按指定格式扫描输入的数据

3.1 Scan

从标准输入扫描文本,读取由空白符分隔的值保存到传递给本函数的参数中,换行符视为空白符。

本函数返回成功扫描的数据格式和遇到的任务错误,若读取的数据个数比提供的参数少,会返回一个错误报告原因。

1、接收一个参数:

package main

import "fmt"


func main() {
    var name string
    fmt.Println("请输入用户名:")
    fmt.Scan(&name)
    fmt.Printf(name)
}

输出:

[root@localhost test]# go run test.go 
请输入用户名:
rose
rose

2、接收两个参数:

package main

import "fmt"

func main() {
	var name string
	var age int

	fmt.Println("请输入用户名:")
	_, err := fmt.Scan(&name, &age)
	if err == nil {
		fmt.Println(name, age)
	} else {
		fmt.Println("用户输入数据错误", err)
	}
}

运行结果:

请输入用户名:
rose 18
rose 18

3.2 Scanln

类似 Scan,遇到换行时才停止扫描,最后一个数据后面必须有换行或者到达结束位置。

返回成功扫描的数据个数和遇到的任何错误。

package main

import "fmt"

func main() {
	var (
		name string
		age int
		gender string
	)
	fmt.Println("请输入参数:")
	fmt.Scanln(&name, &age, &gender)
	fmt.Println(name, age, gender)
}

运行结果:

// 空格不会停止扫描
请输入参数:
rose 19 female
rose 19 female

// 回车会停止扫描
请输入参数:
rose
rose 0 

3.3 Scanf

从标准输入扫描文本,根据 format 参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中。

返回成功扫描的数据个数和遇到的任何错误。

package main

import "fmt"

func main() {
	var (
		name string
		age int
	)
	fmt.Println("请输入参数:")
	_, _ = fmt.Scanf("我叫:%s 今年:%d 岁", &name, &age)
	fmt.Println(name, age)
}

fmt.Scanf 不能以简单的空格符作为输入数据的分隔符,它指定了具体的输入格式,只有按照格式输入数据才会被扫描并存入对应变量,否则不能正确扫描到输入的数据。

3.4 读取一整行

fmt.Scan 以空白符区分输入的参数,若输入的是一整行,且单次之间相互有空格,那么使用 fmt.Scan 就会报错,若想读取一整行可以使用:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	// line 从 stdin 中读取一行的数据,字节集合,转换为字符串
	line, _, _ := reader.ReadLine()
	data := string(line)
	fmt.Println(data)
}

运行结果:

// 输入的数据
格式化输入输出的用法请参考 aaaa fff gghh arr

// 打印的数据
格式化输入输出的用法请参考 aaaa fff gghh arr

reader 默认一次能读取 4096 个字节,一次性读完:isPrefix=false,先读一部分:isPrefix=true,再去读取:isPrefix=false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风老魔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值