Go语言基础学习

环境安装

本文使用go版本 1.14.4
系统环境: Win 10

官方下载地址:
https://golang.org/dl/
https://golang.google.cn/dl/

第三方下载: Go语言中文网
https://studygolang.com/dl

安装直接下一步下一步即可

go语言特点

Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率

  • 从C语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和C语言一样的编译执行方式及弱化的指针。
  • 引入包的概念,用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在。
  • 垃圾回收机制,内存自动回收。
  • 天然并发
    (1)从语言层面支持并发,实现简单
    (2) goroutine,轻量级线程,可实现大并发处理,高效利用多核。
    (3)基于CPS并发模型( Communicating Sequential Processes)实现
  • 吸收了管道通信机制,形成Go语言特有的管道 channel通过管道 channel,可以实现不同的 goroute之间的相互通信。
  • 新的创新:比如切片 slice、延时执行 defer

在这里插入图片描述

基础语法

数据类型

在 Go 编程语言中,数据类型用于声明函数和变量。

数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。

Go 语言按类别有以下几种数据类型:

  • 布尔型 : true 或 false
  • 数字类型 : int,float32,float64,支持复数【uint,uint8,uint16,uint32,uint64,int,int8,int16,int32,int64,uintptr,byte,rune,float32,float64,complex64,complex128】
  • 字符串 : 字符串的字节使用 UTF-8 编码标识 Unicode 文本
  • 其它派生类型: 指针(Pointer),数组,结构化类型(struct),函数,切片,Channel,Map,interface等。
    说明: uintptr存放指针,rune代表一个字符,和java中的Char一样,rune是32位。byte类似uint8

整数类型

类型有无符号占用存储空间数值范围备注
int81字节-128 ~ 127
int162字节-215 ~ 215 -1
int324字节-231 ~ 231 -1
int648字节-263 ~ 263 -1
int32位系统4字节
64位系统8字节
-231 ~ 231 -1
-263 ~ 263 -1
uint32位系统4字节
64位系统8字节
0 ~ 232 -1
0 ~ 264 - 1
rune与 int32一样-231 ~ 231 -1等价 int32
表示一个 unicode码
byte与 uint8等价0 ~ 255存储字符时选用byte

在Go语言中 数值整数默认为 int 类型

如何获取变量的数据类型和占用字节数呢?

     var a int64
	a = 255
	fmt.Printf("a的数据类型: %T",a)
	fmt.Println()
	fmt.Printf("a占用字节数: %d",unsafe.Sizeof(a))

在这里插入图片描述

浮点类型

类型占用存储空间数值范围
float324字节
float648字节

Go语言 小数 默认为 float64

基本数据类型 和 string的转换

基本类型转string

方式一: Sprintf("%参数",表达式)
在这里插入图片描述

  • 参数需要和表达式的类型相匹配
  • fmt.Sprintf 会返回转换后的字符串
    var num1 int = 66
	var num2 float64 = 23.45
	var b bool = false
	var ch byte = 's'

	str := fmt.Sprintf("%d", num1)
	fmt.Printf("str type is %T, value = %q\n",str,str)

	str2 := fmt.Sprintf("%f", num2)
	fmt.Printf("str2 type is %T, value = %q\n",str2,str2)

	str3 := fmt.Sprintf("%t", b)
	fmt.Printf("str3 type is %T, value = %q\n",str3,str3)

	str4 := fmt.Sprintf("%c", ch)
	fmt.Printf("str4 type is %T, value = %q\n",str4,str4)

在这里插入图片描述
方拾二: 使用strconv包函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    var num1 int = 66
	var num2 float64 = 23.45
	var b bool = true

	str := strconv.FormatInt(int64(num1),10)
	fmt.Printf("str type is %T, value = %q\n",str,str)

	str2 := strconv.FormatFloat(num2,'f',10,64)
	fmt.Printf("str2 type is %T, value = %q\n",str2,str2)

	str3 := strconv.FormatBool(b)
	fmt.Printf("str3 type is %T, value = %q\n",str3,str3)

在这里插入图片描述

string转基本数据类型

方案: 使用 strconv包下的函数处理
在这里插入图片描述
func ParseBool
func ParseBool(str string) (value bool, err error)
返回字符串表示的bool值。它接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE;否则返回错误。

func ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)

返回字符串表示的整数值,接受正负号。

base指定进制(2到36),如果base为0,则会从字符串前置判断,"0x"是16进制,"0"是8进制,否则是10进制;

bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64;返回的err是*NumErr类型的,如果语法有误,err.Error = ErrSyntax;如果结果超出类型范围err.Error = ErrRange。

func ParseUint

func ParseUint(s string, base int, bitSize int) (n uint64, err error)

ParseUint类似ParseInt但不接受正负号,用于无符号整型。

func Atoi
func Atoi(s string) (i int, err error)
Atoi是ParseInt(s, 10, 0)的简写。

func ParseFloat
func ParseFloat(s string, bitSize int) (f float64, err error)
解析一个表示浮点数的字符串并返回其值。

如果s合乎语法规则,函数会返回最为接近s表示值的一个浮点数(使用IEEE754规范舍入)。bitSize指定了期望的接收类型,32是float32(返回值可以不改变精确值的赋值给float32),64是float64;返回值err是*NumErr类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值f为±Inf,err.Error= ErrRange。

    var str string = "true"
	b, _ := strconv.ParseBool(str)
	fmt.Printf("b type is %T, value = %v\n",b,b)

	var str2 string = "12345"
	num, _ := strconv.ParseInt(str2, 10, 0)
	atoi, _ := strconv.Atoi(str2)
	fmt.Printf("num type is %T, value = %v\n",num,num)
	fmt.Printf("atoi type is %T, value = %v\n",atoi,atoi)

	var str3 string = "3.14"
	float, _ := strconv.ParseFloat(str3, 64)
	fmt.Printf("float type is %T, value = %v\n",float,float)

在这里插入图片描述

变量

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字:

变量声明

第一种,指定变量类型,如果没有初始化,则变量为系统默认值。

var identifier type

如果定义变量,但没有初始化,则这些变量会有默认初始值

  • 数值类型 初始为0
  • 布尔类型 初始为 false
  • 字符串类型 初始为 “”
package main

import "fmt"

func main() {
	//fmt.Println("hello world")
	varInit()

}
func varInit()  {
	var i int
	var f float64
	var b bool
	var s string
	fmt.Printf("%v %v %v %q\n", i, f, b, s)
}

结果为:
在这里插入图片描述
第二种,根据值自行判定变量类型。

var v_name = value
func main() {
   var num = 3
   var b = true
   fmt.Println(num,b)
}

第三种,省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误,格式:

v_name := value
func main() {
   a,b,c,d := 1,2,true,"你好"
   fmt.Println(a,b,c,d)
}

输出结果:

1 2 true 你好

常量

常量一旦被初始化,就不能被修改。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型

显式类型定义: const b string = “abc”
隐式类型定义: const b = “abc”

常量还可以用作枚举:

func enums()  {
	const (
		cpp = 0
		java = 1
		python = 2
		golang = 3
	)
}

条件语句

if else

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else {
  /* 在布尔表达式为 false 时执行 */
}

示例

package main
import (
	"fmt"
	"io/ioutil"
)
func main() {
	const filename = "abc.txt"
	contents,err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
	}else{
		fmt.Println(string(contents))
	}

}

在这里插入图片描述
在这里插入图片描述
上面代码还有一种写法

package main
import (
	"fmt"
	"io/ioutil"
)

func main() {
	readfile_2()
}

func readfile_2(){
	const filename = "abc.txt"
	**if contents,err := ioutil.ReadFile(filename); err != nil {
		fmt.Println(err)
	}else{
		fmt.Println(string(contents))
	}**
}
  • if 条件里面可以赋值
  • if 条件里赋值的变量的作用域就在改 if 语句块里

switch

  • switch 每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。

  • switch 匹配项后面也不需要再加 break。

  • switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough

func grade(score int) string {
	level := ""
	switch {
	case score < 0 || score > 100:
		panic(fmt.Sprint("Wrong score: %d",score))
	case score < 60:
		level = "F"
	case score < 80:
		level = "C"
	case score < 90:
		level = "B"
	case score <= 100:
		level = "A"
	}
	return level
}
  • switch 语句后可以没有表达式,在case后加入条件

循环语句

for 循环

for init; condition; post { }
  • init: 一般为赋值表达式,给控制变量赋初值;
  • condition: 关系表达式或逻辑表达式,循环控制条件;
  • post: 一般为赋值表达式,给控制变量增量或减量。

注意:

  • for循环里不需要括号
  • for循环可以省略初始条件,结束条件,递增表达式

示例: 将10进制整数转为2进制

package main
import (
	"fmt"
	"strconv"
)
func main() {
	fmt.Println(convertToBinary(5),convertToBinary(6))
}
func convertToBinary(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result += strconv.Itoa(lsb)
	}
	return result
}

结果如下
在这里插入图片描述

示例2: 一行行的读取文本内容

package main

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

func main() {
	readFile("abc.txt")
}

func readFile(filename string) {
	file,err := os.Open(filename)  //打开文件 file是io流
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)

	for scanner.Scan() { //一行行的扫描
		fmt.Println(scanner.Text())
	}

}

指针

一个指针变量可以指向任何一个值的内存地址,它所指向的值的内存地址在 32 和 64 位机器上分别占用 4 或 8 个字节,占用字节的大小与所指向的值的大小无关。当一个指针被定义后没有分配到任何变量时,它的默认值为 nil。指针变量通常缩写为 ptr。

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&操作符(前缀)来获取变量的内存地址(取地址操作),格式如下:

ptr := &v    // v 的类型为 T

其中 v 代表被取地址的变量,变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为*T,称做 T 的指针类型,*代表指针。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

  • 对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
  • 指针变量的值是指针地址。
  • 对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。

示例1,交换变量数值

func main() {
	a,b := 3,4
	swap(&a,&b)
	fmt.Println(a,b)
}

func swap(a,b *int) {
	*a,*b = *b,*a
}

写法2

func swap2(a,b int) (int,int){
	return b,a
}

未完,…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值