学完js转go-基础知识

js和golang的区别

声明函数

js定义函数为function

golang为func

声明变量

js定义变量为var let,常量为const,js会预编译

找出所有的变量声明,按照变量名加入全局对象,如果已经存在,忽略找出所有的函数声明,按照函数名加入全局对象,如果已经存在同名同名变量或函数,替换非声明不理睬
example: var a=1; var a=b;

golang声明变量为var,常量为const

1.显示完整声明

var varName dataType [=value]

关键字 var用于变量声明
varName是变量名标识符
Go的变量声明后会立即为其分配空间

 var a int =1 var a int =2*3 var a int=b;
2.短类型声明

varName :=value
:=声明只能出现在函数内(包括在方法内)2
此时go编译器会自动进行数据类型判断
Go支持多个类型变量同时声明并赋值。例如:

a,b:=1,"hello"

go中没有见过的关键字

ranage(for循环使用的关键字) fallthrough(switch和select语句使用的关键字)

声明复合数据结构的4个关键字

struct //定义结构类型关键字

interface //定义接口类型关键字

map //声明或创建map类型关键字

chan //声明或创建通道类型关键字

内置函数,不需要import

1.node中为 console process assert buffer MDN上的原生js对象上的方法

2.golang中为make new len cap append copy delete panic recover close complex real image print println

golang中的常量标识符

true false //true和false表示 bool类型的两常量值:真和假

iota //用在连续的枚举类型的声明中

nil //指针/引用型的变量的默认值就是null

GO中的指针

类似与C语言,也等同于其他高级语言的引用

  1. 在赋值语句中,*T出现在"=“左边表示指针声明,*T出现在”="右边表示取指针指向的值(varName为变量名)。示例如下:
var a=11
P:=&a  //*p和a的值都是11
  1. 结构体指针访问结构字体仍然使用".“点操作符,Go语言没有”->"操作符。例如:
type User struct{
name string
age int
}
andes:User{
name:"andes",
age:18,
}
p:=&andes
fmt.Println(p.name)
  1. Go不支持指针的运算。在C和C++里面指针运算很容易出问题,因此Go直接在语言层面禁止指针运算。例如:
a:=1234
p:=&a
P++ //不允许,报non-numeric type *int错误
  1. 函数中允许返回局部变量的地址
 func sum(a,b int)*int{
 sum:=a+b
 return &sum //允许,sum会分配在heap上
}

go中的数组

js声明数组相当简单,并且没有强制要求,并且数组长度可以动态改变,元素类型也不固定

var a=[]
var b=[1,object,[],function,'hhh']

go中数组的类型名是 [n]elementType,其中n是数组长度,elementType是数组元素类型。比如一个包含2个int类型元素可表示为[2]int。数组一般在创建时通过字面量初始化(其他强类型语言也差不多),单独声明一个数组类型变量不进行初始化时没有意义的。

var arr [2]int //声明一个有两个整形的数组,但元素默认值都是0,一般很少这样使用
array:=[...]float64{7.0,8.5,9.1}//[...]后面跟字面量初始化列表

数组初始化

var arr=[2]int{1,2} //全局定义数组

a:=[3]int{1,2,3} //指定长度和初始化字面量
a:=[...]int{1,2,3} //不指定长度,但是由后面的初始化列表数量来确定其长度
a:=[3]int{1:1,2:3} //指定总长度,并通过索引值进行初始化,没有初始化元素时使用类型默认值
a:=[...]int{1:1,2:3} //不指定总长度,通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元素被初始化为类型的零值

数组的特点

  • 数组创建完长度就固定了,不可以再追加元素。
  • 数组是值类型的,数组赋值或作为函数参数都是值拷贝。(和js差不多)
  • 数组长度是数组类型的组成部分,10[int]和20[int]表示不同的类型。
  • 可以根据数组创建切片
数组相关操作。示例如下:

1.数组元素访问。示例如下:

a:=[...]int{1,2,3}
b:=a[0]
//go中的循环不打括号
for i,v:=range a{
}        //range循环和js的var in循环类型

2.数组长度。示例如下:

a:=[...int]{1,2,3}
alength:=len(a)
for i:=0;i<alength;i++{
}

切片

Go语言的数组的定长性和值拷贝限制了其使用场景,Go提供了另一种数据类型slice,这是一种边长数组,其数组结构中有指向数组的指针,所以是一种引用类型。例如:

type slice struct{
	array unsafe.Pointer
	len int
	cap int
}

学完js转go-基础知识_第1张图片

1.数组创建
  • 由数组创建
    创建语法如下:array[b:e] b表示开始索引,可以不指定,默认为0;e表示结束索引,可以不指定,默认是len(array)。
var array=[...]int{0,1,2,3,4,5,6}
s1:=array[0:4]
s2:=array[:4]
s3:=array[2:]
fmt.Printf("%v\n",s1)//[0 1 2 3]
fmt.Printf("%v\n",s2)//[0 1 2 3]
fmt.Printf("%v\n",s3)//[2 3 4 5 6]
  • 通过内置函数make创建切片
//len=10,cap=10
a:=make([]int,10)
//len=10,cap=15
b:=make([]int,10,15)

直接声明切片类型变量是没有意义的。例如:

var a []int
fmt.Printf("%v\n",a) //结果为[]

此时切片a的底层数据结构如图所示.

学完js转go-基础知识_第2张图片
nil是引用类型的默认值

2.切片支持的操作
  • 内置函数len()返回切片长度
  • 内置函数cap()返回切片底层数组容量
  • 内置函数append()对切片追加元素
  • 内置函数copy()用于复制一个切片
a:=[...]int{0,1,2,3,4,5,6}
	b:=make([]int,2,4)
	c:=a[0:3]
	fmt.Println(b)
	fmt.Println(len(b)) //2
	fmt.Println(cap(b)) //4
	b=append(b,1)
	fmt.Println(b)
	fmt.Println(len(b)) //[0,0,1]
	fmt.Println(cap(b))	//3
	fmt.Println(c)	//[0,1,2]
	fmt.Println(len(c)) //3
	b=append(b,c...)	
	fmt.Println(b)     //[0 0 1 0 1 2]
	fmt.Println(len(b))	//6
	fmt.Println(cap(b)) //8

	d:=make([]int,2,2)
	copy(d,c)		//copy只会复制d和c中长度最小的
	fmt.Println(d) //[0 1]
	fmt.Println(len(d)) //2
	fmt.Print(cap(d)) //2
3.字符串和切片的相关转换。例如:
str:="hello,世界!"
	a:=[]byte(str)
	b:=[]rune(str)
	fmt.Println(a)  //[104 101 108 108 111 44 228 184 150 231 149 140 239 188 129]
	fmt.Println(b) //[104 101 108 108 111 44 19990 30028 65281]

map

go内置的字典类型叫map.map的类型格式是map[K]T,其中K可以是任意可以进行比较的类型,T是值类型。map也是一种引用类型。
js中Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

map的创建
  • 使用字面量创建.例如:
ma:=map[string]int{"a":1,"b":2}
fmt.Println(ma["a"])
fmt.println(ma["b"])
  • 使用内置的make函数。例如:
make(map[k]T) //map的容量使用默认值
make(map[k]T) //map的容量使用给定的len值
mp1:=make(map[int]string)
mp2:=make(map[int]string,10)
mp1[1]="tom"
mp2[1]="pony"
fmt.Println(mp1[1]) //tom
fmt.Println(mp2[1]) //pony
  • map支持的操作
    再js中如这张图

学完js转go-基础知识_第3张图片
go中
1.map的单个键值访问格式为mapName[key],更新某个key的值时mapName[key]放到等号左边,访问某个key的值时mapName[key]放在等号的右边
2.可以使用range遍历一个map类型变量,但是不保证每次迭代元素的顺序
3.删除map中的某个键值,使用语法:delete(mapName,key)。delete是内置函数,用来删除map中的某个键值对。
4.可以使用内置的len()函数返回map中的键值对数量。

mp:=make(map[int]string)
mp[1]="tom"
mp[2]="pony"
mp[3]="andes"
delete(mp,3)
fmt.Println(mp[1])
fmt.Println(len(mp))
for k,v:=range mp{
 fmt.println("key=",k,"value",v)
}
//key 1 value= tom
//key 2 value= pony
//key 3 value= jaky

注意

  • Go内置的map不是并发安全的,并发安全的map可以使用标准包sync中的map。
  • 不要直接修改map value内某个元素的值,如果修改map的某个键值,则必须整体赋值。例如:
type User struct{
name string
age int
}
ma:=make(map[int] User)
andes:=User{
name:"andes",
age:18,
}
ma[1]=andes //EPPOR,不能通过map引用直接修改
andes.age=19
ma[1]=andes //必须整体替换value,有点类似于rdeux中reducer返回一个新的state
fmt.Printf("%\n",ma)

struct

go中struct类型与C类似,中文翻译为结构,由于多个不同类型元素组合而成。这里面有两层含义:第一,struct结构中的类型可以是任意类型;第二,struct的存储空间是连续的,其字段按照声明时的顺序存放

1.struct类型字面量。
struct类型字面量的声明格式如下:

struct{
	FieldName FieldType
	FieldName FieldType
	FieldName FieldType
}

2.自定义struct类型。
自定义struct类型声明格式如下:

type TypeName struct{
    FieldName FieldType
	FieldName FieldType
	FieldName FieldType
}

3.sturct类型变量的书初始化

type Person struct{
Name string
Age int  
}
type Student struct{
*Person
Number int
}
P:=&Person{
Name:"tata",
Age:12,            //最后一定要个逗号,不然会报错
}
s:=Student{
Person:p,
Number:110,     //最后一定要个逗号,不然会报错
}
//如果其中没有指定的字段则默认初始化为类型的零值

for语句

//访问map
for key,value:=range map{}
for key:=range map{}
//访问数组
for index,value:=range array{}
for index:=range array{}
//访问切片
for index,value:=range slice{}
for index:=value slice{}
for _,value:=range slice{}
//访问通道
for value:=range channel{}

goto语句

goto语句只能调到同级作用域或者上层作用域,不能调到内部作用域。

for x := 0; x < 10; x++ {
		for y := 0; y < 10; y++ {
			if y == 2 {
				// 跳转到标签
				goto breakHere
			}
		}
	}
	return
breakHere:
	fmt.Println("done")

你可能感兴趣的:(go)