道者编程

go基础知识(一)语法

一:第一个go程序:

package main
import "fmt"
func main() {
	/* 输出Hello, World!*/
    fmt.Println("Hello, World!")
}

 运行一下:输出:Hello, World!

$ go run hellow.go
Hello, World!
 编译成二进制文件:

cjs@LAPTOP-UQTQL6TT MINGW64 /f/go
$ go build hellow.go

cjs@LAPTOP-UQTQL6TT MINGW64 /f/go
$ ls
hellow.exe*  hellow.go

cjs@LAPTOP-UQTQL6TT MINGW64 /f/go
$ ./hellow.exe
Hello, World!

 知识点:

1:package:包,每一个go源文件开头都必须有1个或多个package声明,表示源文件所属包,Go 语言的编译程序会试图把这种名字的包编译为二进制可执行文件。所有用 Go 语言编译的可执行程序都必须有一个名叫 main 的包。一个可执行程序有且仅有一个 main 包。main()函数是程序的入口。

2:import:导入一个包,fmt 包使用函数实现 I/O 格式化(类似于 C 的 printf 和 scanf 的函数)。

3:func:函数,相当于php中的function

4:func main(){ 这里一定要注意,这个 { 不能单独一行。比如以下是错的:

func main()
{ //这种写法是错的,{  不能单独一行。

}

5:注释:/* */  或者//,这个和PHP差不多

6:go run:执行go程序

7:go build:编译打包代码为exe可执行程序

二:语言结构

go语言包括以下几个部分:包声明,引入包,函数,变量,语句 & 表达式,注释

三:基本语法

1:行分隔符:php每行结束是分号标识,G语言不需要,除非多个语句写在一行,那么中间用分号隔开,但这种写法不提倡,看起来不人性化。

2:标识符:标识符用来命名变量、类型等程序实体。字母、数字和下划线组成,但第一个字必须是字母或下划线

3:字符串连接:通过+连接,比如:fmt.Println("Chinese" + "Kung Fu")

四:数据类型

php是弱类型语言,不必向 PHP 声明该变量的数据类型;而go是强类型定义语言,但和java又不一样,go可以定义数据类型,如:var name string = "李小龙",也可以不定义数据类型。个人理解:强类型定义语言,不是必须要声明类型,而是一旦声明了类型,如果不强制转换,那么它永远就只是这个数据类型。PHP开发就比较随意 $name = "李小龙",$name = 123 赋值不同,变量类型就变了。

五:变量与常量

1;变量:php中声明一个变量,是$符号开始,go语言一般用var,三种变量定义。

(1):指定变量数据类型

//声明字符串变量name
var name string

//声明多个变量
var name,name2,name3 string

//如果没有初始化,则变量默认为零值

//声明字符串变量name,初始化值为:李小龙
var name string = "李小龙"
 (2):不指定变量类型

package main
import "fmt"
func main() {
    var d = 123 //没指定变量类型
    fmt.Println(d)
}
 编译器自己判断数据类型

(3):短变量

用来声明和初始化函数内部的局部变量,变量的类型根据表达式自动推导,不能在函数外面使用,而且声明了必须要使用。

package main
import "fmt"
func main() {
   var v int = 0
   v := 1 // 错误 v已经声明过
   fmt.Println(v)
}

再看一个:

package main
import "fmt"
func main() {
   var v int = 0
   // 正确 v虽然已经声明过,但是b没有,
   //所以多个变量声明,左边至少要有一个新变量
   v,b:= 1,2 
   fmt.Println(v) //错误,声明的变量必须使用,这里b没有实际用到
   fmt.Println(v,b) //正确,输出了v和b,使用了变量
}

2:常量

常量用const定义。

const b string = "abc" //显式类型定义
const b = "abc" //隐式类型定

//多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2

六:运算符和PHP差不多,略

七:基本语句

(1):if else

package main
import "fmt"
func main() {
   /* 局部变量定义 */
   var a int = 100;
 
   /* 判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" );
   } else {
       /* 如果条件为 false 则执行以下语句 */
       fmt.Printf("a 不小于 20\n" );
   }
   fmt.Printf("a 的值为 : %d\n", a);
}
 (2):for语句,输出1到100,go没有while语句

package main
import "fmt"
func main() {
  var count = 0
  for count < 100{
  	count++
  	fmt.Println(count)
  }
}
break:用于中断当前 for 循环或跳出 switch 语句。
continue:跳过当前循环的剩余语句,然后继续进行下一轮循环。
goto:将控制转移到被标记的语句。

八:函数

在php中函数以function标识,go语言中用func,在go程序中必须要有mian函数,程序从这里执行,如果不需要返回值可以不用返回类型,否则需要指定返回类型。

1:基本调用

package main
import "fmt"
func main(){ //程序开始
	var a int = 100
	var b int = 200
	var count int
	count = sum(a,b) //调用sum函数
	fmt.Printf("相加为:%d\n",count)
}

func sum(num1 int,num2 int) int{ //返回类型
	return num1+num2
}

// 类型不一样,转换
package main
import "fmt"

func main(){
	var a int = 100
	var b float64 = 200.2
	var count float64

	count = sum(a,b)
	fmt.Printf("相加为:%f\n",count)
}


func sum(a int,b float64) (float64){
	return float64(a)+b // a强制转换为float
}

2:多个返回值

package main
import "fmt"
func main(){
	a,b := "china","shenzhen"
	a,b = swap(a,b)
	fmt.Println(a,b)
}

func swap(x,y string) (string,string){
	return x,y
}

3:入参和返回值不一样

package main
import "fmt"
func main(){
	a,b := "china","shenzhen"
	var c string
	a,b,c = swap(a,b) //返回3个,入参2个
	fmt.Println(a,b,c)
}

func swap(x,y string) (string,string,string){
	return x,y,"中国晚上" // 返回3个
}
 

九:数组

go 语言数组,三种定义方式

package main
import "fmt"

func main() {
	var n[10] int /* 长度为10的数组*/ 
	var i,j int

	/* 数组n初始化值 */
	for i = 0; i<10; i++ {
		n[i] = i+1
	}

	/* 输出每个数组元素值*/
	for j = 0; j<10; j++ {
		fmt.Printf("n[%d] = %d\n",j,n[j])
	}
}

一些基本用法:

var arr1 [3] int   //3个int型的数组,初始值是3个0,定义了数组长度,就不能改
arr2:=[5]int{1,2,3,4,5}   //定义并初始化长度为5的数组,赋值5个。
arr3:=[5]int{1,2,3}   //定义并初始化长度为5的数组,最后两个没赋值为0
var arr2 = [...]int{6, 7, 8} //不声明长度
q := [...] int {1,2,3} //不声明长度
r := [...] int {99:-1}  //长度为100的数组,只有最后一个是-1,其他都是0
 函数定义的返回值和实际返回值要一致

十:指针

一个指针变量指向了一个值的内存地址,取地址符加&,如取变量a的内存地址:&a

十一:结构体struct

结构体可以定义不同的数据类型(数组就做不到),把各种不同类型的数据组合在一起,属于一种聚合类型。

语法结构:type 名称 struct{}

(1):基本用法

package main
import "fmt"

type Books struct{ //定义结构体
	title string
	subject string
	book_id int
}

func main(){ //结构体元素赋值输出

	//这里变量类型为结构体的名称:Books 
	//或者短变量写法 data := Books{"go语言","语言教程",1}
	
	var data Books = Books{"go语言","语言教程",1}
	fmt.Println(data)

	//key value格式
	fmt.Println(Books{title:"go语言",subject:"语言教程",book_id:1})

	//不赋值字段为0或者空
	fmt.Println(Books{title:"go语言",subject:"语言教程"})	
}

(2):访问结构体成员

访问结构体成员用 . 符号,格式:结构体.成员名

package main
import "fmt"

type Books struct{ //定义结构体
	title string
}

func main(){ //结构体元素赋值输出
	var books Books //声明books为 Books 这里用new也可以 books := new(Books)
	books.title = "go语言" //成员赋值
	fmt.Println(books.title) //打印
}

这里就好比php中面向对象用$this->给变量赋值,取值,这里就用 . 

(3):结构体作为函数参数

package main
import "fmt"

type Books struct{ //定义结构体
	title string
	name string
}

func main(){ //结构体元素赋值输出
	var books Books //声明books为 Books 
	books.title = "go语言" //赋值
	books.name = "李小龙" //赋值
	
	abs(books) //调用abs函数
}

func abs(books Books){ //类型为Books
	fmt.Println(books.title)
	fmt.Println(books.name)
}

(4)结构体方法:

基本格式:

package main
import "fmt"

type Point struct{
	name string
	age int
}

/* 
	1:结构体方法比普通方法声明多了一个参数,把方法绑定在此参数上。
	2:此参数为:p 又叫接收器,为某种类型的变量,display为方法
	3:接收器范围:方法绑定到除了指针类型和接口类型的任何类型上
	4:格式为:
	func (接收器变量 接收器类型) 方法名(参数列表) (返回参数) {
	    函数体
	}
*/
func (p Point) display() { // 只有Point实例可以调用 display方法
	fmt.Println(p.name,p.age)
}

func main(){
	p := Point{
		name:"李小龙",
		age:27,
	}
	p.display()
}
十二:语言切片Slice

slice相当于动态的数组,go语言中数组长度不能改变,实际使用中不实用。比如把数据库某些数据提出来,提到数组中,这些数据是动态的,甚至长度可能是不知道的,用数组就没法弄。slice长度是不固定的,可以追加元素。

基本语法:

(1)var 切片名 []type = make([], len, [cap]);参数说明:type是数据类型、len是大小、cap是切片容量(容量必须>=长度)

(2)var 变量名 []变量类型

什么是容量和长度:举个例子,一个杯子可以装500ml水,现在杯子里面有200ml水。容量:500ml,长度:200ml。容量就是杯子的容量,而长度就是杯子实际装了多少。所以这就是容量为啥必须大于等于长度的原因。

通过三种方法创建切片:

// 1:make创建切片,分配内存,初始化
var arr = make([]int,5,10) // make函数长度为5,容量为10
var arr = make([]int,5) //长度为5,容量可以不写

// 2:new 创建切片,只分配内存,不初始化,返回指针
arr := new([]int)
*arr = append(*arr, 1, 2, 3,4,5,6)  //追加
fmt.Println(*arr)

// 3:直接写
var arr = [] int {1,2,3} , // []里面有值就是数组,否则就是切片
arr = append(*arr, 4,5,6)

 追加元素
func main() {
    s := make([]int, 3) //定义长度为3的切片 这里输出为 0 0 0
    s = append(s, 1, 2, 3) //追加3个元素 
    fmt.Println(s) //结果为 0 0 0 1 2 3
}
 len() 和 cap() 函数获取长度和容量
func main() {
    s := make([]int, 3) //定义长度为3的切片 这里输出为 0 0 0
    s = append(s, 1, 2, 3) //追加3个元素 
    fmt.Println(len(s),cap(s)) //分别输出切片长度和容量
}

 截取

func main() {
    var s = []int{1,2,3,4,5}
    // : 符号在左边,表示从头截取到第3个为止,输出:[1 2 3]
    fmt.Println(s[:3]) 
    // : 符号在右边,表示截取第3个以后的,输出:[4 5]
    fmt.Println(s[3:])
    // : 符号在中间,表示截取1和3之间的,输出:[2 3] 
    fmt.Println(s[1:3]) 

}

 复制拷贝

/* 拷贝 numbers 的内容到 numbers1 */
   copy(numbers1,numbers)

十三:range 关键字key-val

func main(){
	nums := []int{2, 3, 4}
    count := 0
    // 循环nums
    for _, val := range nums { // _下划线表示不输出索引
        count += val //累加
    }
   fmt.Println("sum:", count) //输出 9
}
func main() {
    nums := []int{2, 3, 4}
    // 循环nums
    for i, v := range nums { // i 为key
    	nums[i] = v
        fmt.Println("index:", i) //输出key
    }
}
 
// 字符串遍历
var str = "hello 你好"
for key, value := range str {
    fmt.Printf("key:%d value:%c\n", key, value) // %c:输出给定整数的对应字符
}
 


最新评论:
2楼 广东省深圳市 电信 发表于 2019-07-30 16:41:24
牛逼楼主!
共有 1 条记录  首页 上一页 下一页 尾页 1
我要评论:

看不清楚