golang学习之旅

1.基本熟悉,了解组成
package main   //main特殊包名,表示是一个可执行程序
//导入代码包,fmt
import "fmt"



//定于全局变量var
var Pi float32   //显式定义
var aname1="你好"
var (
	a11=1
	a22="x"
)


//init函数是初始化实体
func init()  {
	Pi=2+1
}


//程序主体  func函数  main程序主函数
func main()  {
//注释
	//单行注释
	/*多
	  行
	  注
	  释
	*/

	fmt.Println("Hello word")
//常量  定义使用const  数据类型智能判断
	const name string  = "你好"  //显式定义
	const age int =123
	const name2 = "你好"  //隐式定义
	const age2  = 456
	const name3  = "你" +
		"好"




	//:=赋值运算符定义返回变量,但一定要被使用
	n := "hello"
	l := len(n)
	fmt.Println(l)

	//并行赋值
	const (
		Monday,Tuesday,Wednesday=1,2,3
	)
	//枚举
	const (
		a = iota; //a===0
		b
		c
		h="h"
	)
	fmt.Println(c)
	//init函数使用
	DPi := Pi
	fmt.Println(Pi,DPi)
}
2.整型,浮点,字符串
package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println("你好")
	//数据类型
	//整形
	const  value_int_1   int =132
	value_int :=4
	fmt.Println(value_int,value_int_1)
	//浮点
	const value_float float32 =123.123
	value_float_1 := 123.1234
	fmt.Println(value_float,value_float_1)
    //复数(无需要,暂不了解)
    //字符和字符串
    str1:="1234567"
    fmt.Println("字符串长度为:",len(str1))
    //遍历获取每个字符
	for i:=0;i<len(str1) ;i++  {
		//返回字节值
		fmt.Println("每个字符为",str1[i])
		fmt.Println("每个字符为",string(str1[i]))
		//获取单个字符的值
        fmt.Printf("%d = %v\n",i+1,str1[i])
	}
	//非解释字符串
	str2:="你好\n圣姑"
	fmt.Println(str2)
	str3:=`你好\n圣姑`
	fmt.Println(str3)
   //字符串修改  通过byte和rune类型
   str_a1 :="hello word"
   str_a2 :=[]byte(str_a1) //自动复制数据
   str_a2[5]=','  //修改下标为5的值为,
   fmt.Printf("%s\n",str_a2)
   str_a3:=[]rune(str_a1)//转rune
   str_a3[5] =','
   fmt.Println(string(str_a3))  //注意输出的Println   并使用了string函数方法
   fmt.Println(string(str_a3[2])) //获取最后一个字符
   //string包
   //1)判断
   //前后缀包含
   str_b1 :="There is dongxi 你好"
   is_bool := strings.HasPrefix(str_b1,"Th")  //HasPrefix判断
   fmt.Println(is_bool) //返回值
   //字符串包含

   is_bool_1 := strings.ContainsAny(str_b1,"T")
   fmt.Println(is_bool_1) //返回值
   is_bool_2 := strings.ContainsAny(str_b1,"T & e")//多个配
   fmt.Println(is_bool_2) //返回值
   is_bool_3 := strings.ContainsAny(str_b1,"") //false
   fmt.Println(is_bool_3) //返回值


	is_bool_4 := strings.Contains(str_b1,"T")
	fmt.Println(is_bool_4) //返回值
	is_bool_5 := strings.Contains(str_b1,"T & e") //无法多个配
	fmt.Println(is_bool_5) //返回值
	is_bool_6 := strings.Contains(str_b1,"")  //true
	fmt.Println(is_bool_6) //返回值
	//2)索引
	//索引,返回索引值,开头索引值
	is_bool_7 := strings.Index(str_b1,"ere")
	fmt.Println(is_bool_7) //返回值
	fmt.Println("最后一次索引",strings.Index(str_b1,"x"))
	fmt.Println("最后一次索引",strings.Index(str_b1,"z"))
	fmt.Println("最后一次索引",strings.Index(str_b1,"你"))
	fmt.Println("最后一次索引",strings.IndexRune(str_b1,'你')) //非ASCII编码配。一般无用
//3)替换
	str:="你好世界,世界good"
	println(strings.Replace(str,"你好","加油",1))

	//4)统计
	//出现频率
	fmt.Printf("%d\n",strings.Count(str,"o"))
	//字符串数量
	fmt.Printf("%d\n",len([]rune(str)))//[]rune(str)转字节
	fmt.Println(utf8.RuneCountInString(str)) //使用RuneCountInString函数做统计
	//5)大小写转换
	str_e :="here is  my"
	fmt.Println(strings.ToLower(str_e))  //全转为小写
	fmt.Println(strings.ToUpper(str_e))  //全转为大写
	//6)修剪
	fmt.Println(strings.Trim("!!! golang !!!","! "))//Trim使用
	fmt.Println(strings.Trim("!!! golang !!!"," !"))
	fmt.Println(strings.Trim("!!! golang !!!","!"))

	fmt.Println(strings.TrimLeft("!!! golang !!!","! "))//TrimLeft使用
	fmt.Println(strings.TrimRight("!!! golang !!!","! "))//TrimRight使用
	//7)分割
	//返回的是一个切片
	results:=strings.Split("a,c,d",",")
	fmt.Println(results)
	fmt.Println(string(results[0]))
	//8)插入字符

	strSli:=strings.Fields("a b c d") //Fields转为切片
	strSli_2:=strings.Fields("你 的 名 子")
	for _,val:=range strSli{
		fmt.Printf("%s",val)  //获取每个切片的值
	}

	strStr2:=strings.Join(strSli,";") //join的连接符号为;
	fmt.Println(strStr2)//得到结果值
    fmt.Println(strSli_2) //获得
}
3.字符串格式化
含义格式化指令含义
%%%字面量
%b一个二进制整数,将一个整数格式化为二进制的表达方式
%c一个Unicode的字符
%d十进制数值
%o八进制数值
%x小写的十六进制数值
%X大写的十六进制数值
%U一个Unicode表示法表示的整型码值,默认是4个数字字符
%s输出以原生的UTF-8字节表示的字符,如果console不支持UTF-8编码,则会输出乱码
%t以true或者false的方式输出布尔值
%v使用默认格式输出值,或者如果方法存在,则使用类型的String()方法输出的自定义值
%T输出值的类型
4.基础数据类型的扩展
package main

import "fmt"

type (
	字符串 string
)



func main() {
	//1.强转类型
	sum:=11
	count:=3
	mean:=float32(sum)/float32(count)
	fmt.Printf("mean值为%f\n",mean)
	//2.自定义类型。即结构体,后面有详解
	//3.类型别名
    var b 字符串  //显式声明
	b="这是中文"
	fmt.Println(string(b))
    //4.指针
    //指针是一个内存位置,每个内存位置都有其定义的地址,可以使用&运算符访问
    a:=10
    fmt.Printf("%x\n",&a)
    //*访问指针变量的值
    a1:=14
    ap:=&a1
    fmt.Printf("a1的地址%x\n",&a1)
	fmt.Printf("ap的地址%x\n",ap)
	fmt.Printf("*ap的值%d\n",*ap)
    //nil指针
    var ptr *int
    fmt.Printf("ptr的值是%x\n",ptr)
    //指针的指针
    a_n:=10
    aP:=&a_n  //指针
    aPP:=&aP  //指针的指针
    fmt.Printf("aP: %x\n",aP)
	fmt.Printf("aPP: %x\n",*aPP)
    fmt.Printf("aPP: %d\n",**aPP)
    //指针的数据
    a_list:=[]int{10,100,200}
    var p_a [3]*int  //声明指针数组
	for i:=0; i<3;i++  {
		p_a[i]=&a_list[i]  //存储指针的的内存地址
		fmt.Printf("p_a[%d]的内存地址:%x\n",i,p_a[i])
	}
	for i:=0; i<3;i++  {
		fmt.Printf("p_a[%d]的实际值:%d\n",i,*p_a[i])
	}
	//传递给函数
	a3:=100
	b3:=200
	fmt.Printf("交换之前的a,b值为%d,%d\n",a3,b3)
	swap(&a3,&b3)
	fmt.Printf("交换之后的a,b值为%d,%d\n",a3,b3)




}
func swap(x *int,y *int)  {  //指针作为函数参数
	var temp int
	temp=*x
	*x=*y
	*y=temp
}
5.流程控制
package main

import (
	"fmt"
	"go/types"
	"reflect"
)
//空接口
var x interface{}

func main() {
	//流程控制
	//1.条件语句
	a:=100
	if a>200 {
     fmt.Println("大于200")
	}else if a<200{
		fmt.Println("小于200")
	}else {
		fmt.Println("等于200")
	}
	//初始化子语句
	if b:=100;b<200{
		fmt.Println("小于200")
	}
	//2.选择语句
	case_var:=90
	switch case_var {
	case 90:
		fmt.Println("是90")
	case 100:
		fmt.Println("是100")
	default:
		fmt.Println("啥也不是")
	}
   //switch二种用法
	switch  {
	case case_var>100:
		fmt.Println("大于100")
	case case_var<100:
		fmt.Println("小于100")
	default:
		fmt.Println("啥也不是")
	}
	//switch三种用法,多表达
	switch_a:="A"
	switch_b:="B"

	switch  {
	case switch_a=="A" && switch_b=="C":
		fmt.Println("等于A")
	case switch_a=="A" && switch_b=="B":
		fmt.Println("等于A和B")
	default:
		fmt.Println("啥也不是")
	}
	//类型switch
	x=1
	switch i := x.(type) {   //x.(type)只能用在switch中
	case types.Nil:
		fmt.Printf("这里是nif类型,值是%T",i)
	case int:
		fmt.Printf("这里是int类型,值是%T",i)
	case float64:
		fmt.Printf("这里是float64类型,值是%T",i)
	case bool:
		fmt.Printf("这里是bool类型,值是%T",i)
	case string:
		fmt.Printf("这里是string类型,值是%T",i)
	default:
		fmt.Printf("未知类型")

	}
	fmt.Printf("\n")
	//附录
	fmt.Printf("v1的数据类型为:%s\n", reflect.TypeOf(switch_a))
    //初始化语句
	switch case_var_1:=120;case_var_1 {
	case 90:
		fmt.Println("是90")
	case 120:
		fmt.Println("是120")
	default:
		fmt.Println("啥也不是")
	}
    //
	switch switch_c:="C"; {
	case switch_c=="A" :
		fmt.Println("等于A")
	case switch_c=="C" :
		fmt.Println("等于C")
	default:
		fmt.Println("啥也不是")
	}
	//select语句,暂时用不到,select随机选择一个case来判断

	//3、循环语句
	for a:=0; a<5;a++  {
		fmt.Printf("当前数值为%d\n",a)
	}
	//for的子语句
    a1:=0
    b1:=5
	for a1<b1  {
		fmt.Printf("当前数值为%d\n",a1)
		a1++
	}
    //range子语句  类似迭代器  轮询数组或者切片的每一个元素  轮询字符串的每一个字符  字典的键值对  通道类型值元素
    str_a:="abcd"
    for i,char := range str_a{   //i为index char为具体值
        fmt.Printf("第%d个值是,具体值是%s\n",i,string(char))
	}

	for _,char := range str_a{   //_为忽略index  char为具体值
		fmt.Printf("具体值是%s\n",string(char))
	}

	for i  := range str_a{   //i为index  忽略获取具体指
		fmt.Printf("第%d的下标\n",i)
	}

	for range str_a{
		fmt.Printf("遍历字符串,不做任何操作\n")
	}

	//range的字典和数组尝试
	map_a:=map[string]int{"a":1,"b":2}
	for k,v:=range map_a {
		fmt.Printf("k值为%s,v值为%d\n",k,v)
	}
	//定义一个数据
	number_list:=[]int{1,2,3,4}
	for i,num:=range number_list {
       fmt.Printf("下标值为%d,具体的值为%d\n",i,num)
	}
	number_list2:=[5]int{1,2,3,4}
	for i,num:=range number_list2 {
		fmt.Printf("下标值为%d,具体的值为%d\n",i,num)
	}
	//4,延迟语句
	//defer用于延迟调用的指定函数,defer关键字只出现在函数内部
	//特点:1.defer语句全部执行,函数才算真正结束 2.函数等待defer语句结束后,才执行return
	defer fmt.Println("word")
	fmt.Println("hello")
	//5.标签
	goto L1

	L1:
	for i:=0;i<5 ;i++  {
			fmt.Println("输出内容")
		}
}

注,range的返回值的输出:

右边表达式返回的类型第一个值第二个值
stingindexstr[index],返回的类型rune
array/sliceindexstr[index]
mapkeym[key]
channelelement
6.函数
package main

import (
	"fmt"
	"time"
)

//定义一个函数,参数类型,以及返回值类型
func add(a int,b int)int{
	return a+b
}

//返回值变量预定义
func Max(a int,b int)(maxNum int)  {
	if a>b{
       maxNum=a
	}else{
		maxNum=b
	}
	return  maxNum
}

//2.函数基础
//多返回值
func SumResult_A_B( a int,b int)(int,int)  {
	return a,b
}
//函数作为参数
type FormatFunc func(s string,x,y int )string   //定义函数类型
func pipe(ff func() int )int  {
	return ff()
}
func format(ff FormatFunc,s string,x,y int )string  {
	//定义返回的是ff函数的是三个值
	return ff(s,x,y)
}

//定义一个是否整除2的函数
func isEven(v int)bool{
	if v%2==0{
		return true
	}else {
		return false
	}
}

type boolFunc func(int) bool //声明一个函数类型  int是函数的参数值,即isEven(v int)中的参数值,bool为返回值类型

func filter(slice []int,f boolFunc)[] int{
	var result [] int
	for _,value:=range slice{
		if f(value){   //这里f调用函数,根据传参判断,即,在本例子中即是isEven
             result=append(result,value)
		}
	}
	return result
}

//3.可变参数  不同数据类型
func int_change(args ...int){
	for _,i:=range args {
		fmt.Printf("数是%d\n",i)
	}
}

//闭包
func Adds()func(b int) int  {
	return func(b int) int {
		return b+2
	}
}
func recursion(parse int){
   if parse>1{
   	parse--
   	recursion(parse)
   	fmt.Println("当前获得的递归数值为",parse)
   }
}
//panic的函数使用  panic终止后面的执行的代码
func fullName(firstName *string, lastName *string) {
	if firstName == nil {
		panic("runtime error: first name cannot be nil")
	}
	if lastName == nil {
		panic("runtime error: last name cannot be nil")
	}
	fmt.Printf("%s %s\n", *firstName, *lastName)
	fmt.Println("returned normally from fullName")
}

//recover捕获panic,从而影响应用的行为。获取通过panic传递的error
func genErr(){
	fmt.Println(time.Now(),"正常的语句")  //输出正常的语句
	//定义延时函数
	defer func(){
		fmt.Println(time.Now(),"defer正常的语句")
		panic("第二个错误")    //只会输出第二个panic的
	}()
	panic("第一个错误")   //第一个虽然早已经发生,但是不输出的
}
func throwsPanic(f func())(b bool){
	defer func(){
		if r:=recover();r!=nil{
			fmt.Println(time.Now(),"捕获到的异常:",r)
			b=true
		}
	}()
	f()  //即调用了genErr,无panic,即判断if条件不会成立的
	return b
}





func main() {
	//1.测试小例子
	result_num:=add(1,2)
	fmt.Println(result_num)
	result_max_num:=Max(1,3)
	fmt.Println(result_max_num)
    //函数做参数的函数调用
    s1:=pipe(func() int {
		return 100  //匿名函数当参数
	})   //注意这个怎么调用的偶
    fmt.Println(s1)

	s2:=format(func(s string, x, y int) string {
		return fmt.Sprintf(s,x,y)  //格式化输出返回
	},"值1为%d,值2位%d",10,20)
	fmt.Println(s2)
    slice :=[]int{3,3,4,5,6}
	//函数作为类型
    even:=filter(slice,isEven)
    fmt.Println("even:",even)
    //调用可变参数的函数
	int_change(1,2,3,4,5,6)

	//5.匿名函数与闭包
	return_x:=func(x1,x2 int) int{return x1+x2}(3,4)
	fmt.Println(return_x)
	//闭包。闭包允许调用定义在其他环境下的变量,使得某个函数捕捉一些外部状态。
	//调用闭包
	adds_return:=Adds()(3)
    fmt.Println(adds_return)
	//6、递归函数
	recursion(5)

    //7错误与恢复
    //error的常见处理
 	f, err := os.Open("/test.txt")
	if err != nil {
		fmt.Println("error:",err)
		return
	}
	fmt.Println(f.Name(), "open successfully")*/
	//异常处理
	//需要注意的是,你应该尽可能地使用错误,而不是使用 panic 和 recover。只有当程序不能继续运行的时候,才应该使用 panic 和 recover 机制。
	firstName := "foo"
	lastName:="zhang"
	fullName(&firstName, &lastName)
	fmt.Println("returned normally from main")
	//recover函数
	throwsPanic(genErr)

}


内置函数

内置函数就是不需要进行导入操作就可以直接使用的函数,它们有些可以根据不包进行操作(例如len、cap和append),有些用于系统级的操作(例如panic)。常见内置函数如下所示。

内置函数详解
close用于管道通信。
len用于返回某个类型的长度或数量(字符串、数组、切片、map和管道)。
cap容量的意思,用于返回某个类型的最大容量(只能用于切片和map)。
new、make均用于分配内存,不过new用于值类型和用户定义的类型,如自定义结构,make 用于内置引用类型(切片、map和管道)。它们的用法就像是函数。但是将类型作为参数: new(type)、 make(type)。 new(T)分配类型 T的零值并返回其地址,也就是指向类型T的指针,它也可以用于基本类型: v := new(int)。返回类型T的初始化之后的值,因此它比new做更多的工作。new()是一 个不要忘记它的括号。
copy、 append用于复制和连接切片。
panic、recover两者均用于错误处理机制。
print、println底层打印函数(部署环境中建议使用fmt包) .
complex、 real imag用于创建和操作复数。
7.复合数据类型
package main

import "fmt"

func main() {
/*	1、数组的创建以及常见使用*/
	//复合数据类型
	arrays:=[5]int{1,2,3,4,5}  //固定长的数组
	for _,v:=range arrays { //输出结果值
		fmt.Println(v)
	}
	arrays_a1:=[]int{1,2,3,4,5,6} //非固定长度的数组
	for _,v1:=range arrays_a1 {
		fmt.Print(v1)
	}
	//访问与修改
	fmt.Println("\n")
	array_str1:=[5]string{"a","b","c","d","e"}
	for i:=0;i<len(array_str1) ;i++  {
		fmt.Printf("值的下标为:%d,值是%s\n",i,string(array_str1[i]))
	}
	//修改元素
	array_str2:=[5]string{"a","b","c","d","e"}
	array_str2[0]="a1"
	fmt.Println("值为",array_str2[0])
	//声明与修改指针的数组
	array_str3:=[5]*int{0:new(int),1:new(int)}   //声明指针数组。初始化索引为0和1的数组元素
	*array_str3[0]=10
	*array_str3[1]=20
	fmt.Println("数组的值为:",*array_str3[0])
	array_str4:=[3]*string{new(string),new(string),new(string)} //字符串的指针的初始化这个数组
	*array_str4[0]="a1"
	fmt.Println(*array_str4[0])
    //多维数组
    //二维数组
    array_str1_a:=[4][2]int{{10,10},{20,21},{30,31},{40,41}}
	for i:=0;i<len(array_str1_a);i++  {
		for j:=0;j<len(array_str1_a[i]);j++  {
            fmt.Printf("每个的二维数组的值是%d\n",array_str1_a[i][j])
		}
	}
	//修改array_str1_a
	array_str1_a[0][0]=100
	fmt.Println(array_str1_a)
	//数组传递给函数,最好声明为数组指针,这样在数组作为参数的时候会节省很大的开销。
/*	2.切片操作*/
	//创建切片。make切片量
	//slice:=make([]string,5)  //切片长度为5,容量也是5
	//slice:=make([]string,3,5)  //切片长度为3,容量是5。通过后期操作合并到切片中。注意容量不能小于长度

	//nil切片,又称空切片。不做任何初始化,就会创建一个nil切片
	//sclice:=make([]int,0)
	//sclice:=[]int{}

/*	3.切片的使用*/
	//赋值与分割
	slice_array:=[]int{10,20,30,40,50}
	//创意长度为2个元素,容量为4个元素
	new_slice:=slice_array[1:3]
	for _,v:=range new_slice {
		fmt.Println(v)
	}
	fmt.Println(len(new_slice))
	//切片扩容
	new_slice=append(new_slice,60)
	fmt.Println(new_slice)
	//多维度切片
	array_str1_b:=[][]int{{10,10},{20,21},{30,31},{40,41},{410,123,111}}
	array_c1:=[]int{12,123}
	//切片追加切片
	slice_array=append(slice_array, array_c1...)
	fmt.Println(slice_array)
	//追加多维
	array_str1_b=append(array_str1_b,array_c1)
	fmt.Println(array_str1_b)
	//映射,即字典
	dict:=map[string]string{"a":"1","b":"2","c":"3"}
	//修改键的值
	dict["a"]="123"
	//删除
	delete(dict,"c")
	//追加映射
	dict["d"]="4"
	for k,v:=range dict {
		fmt.Println(k,v)
	}
	//数组中添加map
	Goods := []map[string]string{{"a":"1"},{"1":"23"}}
	fmt.Println(Goods)
	//map中添加数组(映射中添加数组)
	Goods_p:=map[string][]string{"a":{"1","2","3"},"b":{"4","5","6"}}
	fmt.Println(Goods_p)
	//挑战,map中添加数组,数组中添加map
	Goods_p_dic:=map[string][]map[string]string{"map":{{"a":"1"},{"b":"2"}}}
	fmt.Println(Goods_p_dic)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值