go語言
基礎
1.變量定義
局部變量
var name string = "小明";
name := "小明";
全局變量
age := 12;
var (
a int;
b bool;
)
賦值
a,b,c,d=1,2,3,"123";
2.常量
const (
a ,b = iota,iota //初始化值爲0
)
1.1 類型總結
類型 | ⻓度 | 說明 |
---|---|---|
bool | 1 | true, false。不能把⾮零值當作 true。 |
byte | 1 | uint8 |
rune | 4 | int32。存儲 Unicode Code Point。 |
int/uint | 與平臺有關,在 AMD64/X86-64 平臺是 64 位整數。 | |
int8/uint8 | 1 | -128 ~ 127; 0 ~ 255 |
int16/uint16 | 2 | -32768 ~ 32767; 0 ~ 65535 |
int32/uint32 | 4 | -21億 ~ 21億, 0 ~ 42億 |
int64/uint64 | 8 | |
float32 | 4 | 精確到 7 個⼩數位 |
float64 | 8 | 精確到 15 個⼩數位 |
complex64 | 8 | |
complex128 | 16 | |
uintptr | ⾜夠保存指針的 32 位或 64 位整數 | |
array | 值類型 如:[2]int | |
struct | 值類型 | |
string | 值類型 | |
slice | 引⽤類型 如: []int | |
map | 引⽤類型 | |
channel | 引⽤類型 | |
interface | 接⼝類型 | |
function | 函數類型 |
注意:定義的變量或者引用的包必須進行使用,否則會出現錯誤。
2.判斷語句
var a int = 0;
b := 10;
if a < b {
fmt.Printf("a 小於 b");
}
與java類似
3.循環
共有三種用法
第一種與java相同
for a:=0;a<10;a++ {
fmt.Printf("a value is %d\n " ,a);
}
第二種根據條件來判斷與while相同
var a int = 10;
var b int = 20;
for (a < b) {
fmt.Printf("a value is %d\n " ,a);
}
第三種
numbers := [6]int{1,2,3,5};
for i,x:= range numbers {
fmt.Println(x);
}
語言函數
在這裏max中是函數名,括號內是參數值與參數類型,int 是指函數的返回值
func max(num1,num2 int) int{
println(value1,value2);
if (num1 > num2) {
return num1;
} else {
return num2;
}
}
go中的函數與java不一致的地方就是可以定義兩個返回值
func swap(x,y string) (string,string) {
return x,y;
}
變量的作用域
- 局部變量
/*局部變量*/
var a,b,c int;
a = 10;
b = 20;
c = 30;
fmt.Println(a,b,c);
- 全局變量
var g int;
func main() {
a,b := 10,20;
g = a + b;
fmt.Printf("this is g value : %d\n",g);
}
語言數組
- 聲明數組
var arrName[size] int;
- 初始化數組
var arr = [5]int{1,2,3,4,5};
var arr = [...]int{1,2,3,4,5,6};
GO的指針定義
var a int = 10;
//定義指針
var ip *int;
ip = &a;
fmt.Printf("a %x\n",&a);
fmt.Printf("ip %x\n",ip);
fmt.Printf("%d\n",*ip);
- 指針數組
package main;
import "fmt";
const MAX int = 3;
func main() {
//定義一個指針數組
var ptr [MAX]*int;
arr := []int{10,20,30};
for i := 0;i < MAX;i++ {
//賦值只能是地址
ptr[i] = &arr[i];
}
//循環數組
for x,y := range ptr {
//要獲取值需要在y前面加*號
fmt.Println(x,*y);
}
}
- 指向指針的指針
var a int = 10;
var ptr *int;
var pptr **int;
ptr = &a;
pptr = &ptr;
fmt.Println("a的變量值爲",a);
fmt.Printf("ptr 的變量值爲 : %d \n",*ptr);
println("pptr的變量值:" ,**pptr)
- 指針作爲函數傳遞
func main() {
a := 10;
b := 20;
fmt.Println("交換之前的a",a);
fmt.Println("交換之前的b",b);
swmp(&a,&b);
fmt.Println("交換之後的a",a);
fmt.Println("交換之後的b",b);
}
func swmp(x *int, y *int) {
var c int
c = *y;
*y = *x;
*x = c;
}
Go語言的結構體
- 定義結構體
package main;
import "fmt";
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
//類似java中的構造器
fmt.Println(Books{"測試","結果 ","結構體",1});
//也可以採用key - value 的形式
fmt.Println(Books{title:"測試1",author:"測試結果",subject:"結構體",book_id:2});
}
- 結構體的使用
與java的類的概念很像,但是在定義時比java的要精簡的很
import "fmt";
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
var book1 Books;
var book2 Books;
book1.title = "jvm運行原理";
book1.author = "C從入門到精通";
book1.subject = "有你相看的書籍";
book1.book_id = 1;
//第二個
book2.title = "jvm運行原理";
book2.author = "C從入門到精通";
book2.subject = "有你相看的書籍";
book2.book_id = 2;
fmt.Printf("book1.title : %s\n ",book1.title);
fmt.Printf("book2.book_id : %d \n",book2.book_id);
}
- 作爲參數進行傳遞
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
var book1 Books;
var book2 Books;
book1.title = "jvm運行原理";
book1.author = "C從入門到精通";
book1.subject = "有你相看的書籍";
book1.book_id = 1;
//第二個
book2.title = "jvm運行原理";
book2.author = "C從入門到精通";
book2.subject = "有你相看的書籍";
book2.book_id = 2;
printBook(book1);
}
func printBook( book Books ) {
fmt.Printf( "Book title : %s\n", book.title);
fmt.Printf( "Book author : %s\n", book.author);
fmt.Printf( "Book subject : %s\n", book.subject);
fmt.Printf( "Book book_id : %d\n", book.book_id);
}
Go語言切片
使用makx來進行定義
make([]T, length, capacity)
package main;
import "fmt";
func main() {
var numbers = make([]int,3,5);
printSlice(numbers);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
}
切片截取
func main() {
var numbers = []int{1,2,3,4,5,6,7,7,8,8,9};
printSlice(numbers);
fmt.Println(numbers[0:4]);
fmt.Println(numbers[4:]);
fmt.Println(numbers[:4]);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
擴容
func main() {
//var numbers = []int{1,2,3,4,5,6,7,7,8,8,9};
var numbers [] int;
printSlice(numbers);
numbers = append(numbers,12);
printSlice(numbers);
numbers = append(numbers,33,22,11,42);
printSlice(numbers);
// 創建兩倍容量
numbers1 := make([]int,len(numbers),(cap(numbers))*2);
copy(numbers1,numbers);
printSlice(numbers1);
numbers1 = append(numbers1,12,3,123,123,12,3);
printSlice(numbers1);
numbers1 = append(numbers1,12,3,123,123,12,3);
printSlice(numbers1);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
}
範圍range
package main;
import "fmt";
func main(){
var arr = []int{1,2,3};
vs := 0;
for _, v := range arr {
vs += v;
}
fmt.Println(vs);
kvs := map[string]string{"name":"qiao","b":"aaa"};
for k,v := range kvs {
fmt.Printf("k=%s,v=%s\n",k,v);
}
for i,j := range "go" {
fmt.Println(i,j);
}
}
MAP的定義與使用
package main;
import "fmt";
func main() {
//定義map
testMap := make(map[string]string);
testMap["name"] = "csdn";
testMap["age"] = "12";
for k,v := range testMap {
fmt.Printf("k=%s,v=%s\n",k,v);
}
captial,ok := testMap["name"];
if(ok) {
fmt.Println("存在",captial);
}else {
fmt.Println("不存在");
}
//刪除
delete(testMap,"name");
for key := range testMap{
fmt.Println(testMap[key]);
}
}s
類型轉換
語法 : type_name(value);
var a int = 13;
var b int = 3;
result := float32(a)/float32(b);
fmt.Println(int(result),"結果");
定義接口
package main
import (
"fmt"
)
type Phone interface {
call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}
func main() {
var phone Phone
phone = new(NokiaPhone)
phone.call()
phone = new(IPhone)
phone.call()
}
-- 帶返回值的接口
注意在接口中,所有定義的屬性都應該實現
定義錯誤方法
package main;
import (
"fmt"
);
//定義除法結構體
type DivideError struct {
dividee int;
divider int;
}
//實現錯誤接口
func (div *DivideError) Error() string {
strFormat := `
Cannot proceed,the divider is zero
dividee :%d
divider : 0
`
return fmt.Sprintf(strFormat,div.dividee);
}
func Divide(varDividee int,varDivider int) (result int,errMsg string) {
if varDivider == 0 {
eData := DivideError{
dividee : varDividee,
divider : varDivider,
}
errMsg = eData.Error();
return
}else {
return varDividee / varDivider,""
}
}
func main() {
result,errorMsg := Divide(10,0);
if errorMsg != "" {
fmt.Printf("errorMsg : %s",errorMsg);
}else {
fmt.Printf("value is of : %d",result);
}
}
go的csp模型
channel
c := make(chan int)
var send chan<- int = c // send-only
var recv <-chan int = c // receive-only
buffered channel
c := make(chan int , 3)
正常創建的channel,必須立刻有人接受,這樣也是比較消耗性能的
創建buffered後,可以給他一個緩衝區,在達到一定數量後才進行
range
如果沒有範圍控制,在輸出channel時,就會一直進行輸出
理論基礎
Communication Sequential Process (CSP) 通信順序進程
我們通常都是通過共享內存來通信,而go是通過通信來同享內存
最後歡迎大家批評指正,您的建議就是我前進的動力。