go语言基础

1.Go 语言特色

1)简洁、快速、安全
2)并行、有趣、开源
3)内存管理、数组安全、编译迅速

2.Go 语言用途

1)Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言
2)对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。

3.第一个 Go 程序

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
go build hello.go 
./hello 

4.Go 语言结构

Go 语言的基础组成有以下几个部分:

1)包声明
2)引入包
3)函数
4)变量
5)语句 & 表达式
6)注释
注意
需要注意的是 { 不能单独放在一行,所以以下代码在运行时会产生错误

5.Go 语言基础语法

Go 标记

Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号
行分隔符
Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。
如果你打算将多个语句写在同一行,它们则必须使用;

注释

// 单行注释
/*
 我是多行注释
 */

标识符

标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字

字符串连接

Go 语言的字符串可以通过 + 实现

6.Go 语言数据类型

1)布尔型
2)数字类型
3)字符串类型:
4)派生类型:
包括:
(a) 指针类型(Pointer)
(b) 数组类型
(c) 结构化类型(struct)
(d) Channel 类型
(e) 函数类型
(f) 切片类型
(g) 接口类型(interface(h) Map 类型

7.Go 语言变量

变量声明

1)var v_name v_type
2)var v_name = value
3)v_name := value
4)多变量声明
var vname1, vname2, vname3 type

8.Go 语言常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量

const identifier [type] = value
iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量
const (
    a = iota
    b = iota
    c = iota
)

9.Go 语言运算符

Go 语言内置的运算符有:

1)算术运算符
2)关系运算符
3)逻辑运算符
4)位运算符
5)赋值运算符
6)其他运算符

10.Go 语言条件语句

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

	if a < 20 {
		   /* 如果条件为 true 则执行以下语句 */
		fmt.Printf("a 小于 20\n" );
	} else {
		/* 如果条件为 false 则执行以下语句 */
		fmt.Printf("a 不小于 20\n" );
	}
	
   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }

   switch {
      case grade == "A" :
         fmt.Printf("优秀!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" );
   }
   
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   } 

11.Go 语言循环语句

Go 语言的 For 循环有 3 种形式

for init; condition; post { }
for condition { }
for { }
sum := 0
    for i := 0; i <= 10; i++ {
        sum += i
}
		
for sum <= 10{
    sum += sum
}

sum := 0
    for {
        sum++ // 无限循环下去
}

12.Go 语言函数

函数定义

func function_name( [parameter list] ) [return_types] {
   函数体
}

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

13.Go 语言变量作用域

1)函数内定义的变量称为局部变量
2)函数外定义的变量称为全局变量
3)函数定义中的变量称为形式参数

14.Go 语言数组

声明数组
Go 语言数组声明需要指定元素类型及元素个数

var variable_name [SIZE] variable_type

初始化数组

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

多维数组

var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
a = [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11},   /* 第三行索引为 2 */
}

标题15.Go 语言指针

Go 语言的取地址符是 &

指针声明格式

var var_name *var-type

var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针

var ip *int  

如何使用指针
指针使用流程:

1)定义指针变量
2)为指针变量赋值
3)访问指针变量中指向地址的值

Go 空指针

当一个指针被定义后没有分配到任何变量时,它的值为 nil

16.Go 语言结构体

type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}

type Books struct {
   title string
   author string
   subject string
   book_id int
}
var Book1 Books=Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407}

访问结构体成员

结构体.成员名

结构体指针

var struct_pointer *Books

17.Go 语言切片(Slice)

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
定义切片
你可以声明一个未指定大小的数组来定义切片:

var identifier []type

切片不需要说明长度。
或使用make()函数来创建切片:

var slice1 []type = make([]type, len)

也可以简写为

slice1 := make([]type, len)

也可以指定容量,其中capacity为可选参数。

make([]T, length, capacity)

切片初始化

s :=[] int {1,2,3 }

将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片

s := arr[startIndex:endIndex] 

len() 和 cap() 函数
切片是可索引的,并且可以由 len() 方法获取长度。
切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
空(nil)切片

一个切片在未初始化之前默认为 nil,长度为 0

append() 和 copy() 函数
如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。
下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)

   /* 允许追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)

   /* 向切片添加一个元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)

   /* 同时添加多个元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)

   /* 创建切片 numbers1 是之前切片的两倍容量*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)

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

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

18.Go 语言范围(Range)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对

package main
import "fmt"
func main() {
    //这是我们使用range去求一个slice的和。使用数组跟这个很类似
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)
    //在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }
    //range也可以用在map的键值对上。
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }
    //range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

19.Go 语言Map(集合)

Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
定义 Map

  • 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */

map_variable := make(map[key_data_type]value_data_type)
package main

import "fmt"

func main() {
    var countryCapitalMap map[string]string /*创建集合 */
    countryCapitalMap = make(map[string]string)

    /* map插入key - value对,各个国家对应的首都 */
    countryCapitalMap [ "France" ] = "巴黎"
    countryCapitalMap [ "Italy" ] = "罗马"
    countryCapitalMap [ "Japan" ] = "东京"
    countryCapitalMap [ "India " ] = "新德里"

    /*使用键输出地图值 */ 
    for country := range countryCapitalMap {
        fmt.Println(country, "首都是", countryCapitalMap [country])
    }

    /*查看元素在集合中是否存在 */
    capital, ok := countryCapitalMap [ "American" ] /*如果确定是真实的,则存在,否则不存在 */
    /*fmt.Println(capital) */
    /*fmt.Println(ok) */
    if (ok) {
        fmt.Println("American 的首都是", capital)
    } else {
        fmt.Println("American 的首都不存在")
    }
}

20.Go 语言递归函数
package main

import "fmt"

func fibonacci(n int) int {
  if n < 2 {
   return n
  }
  return fibonacci(n-2) + fibonacci(n-1)
}

func main() {
    var i int
    for i = 0; i < 10; i++ {
       fmt.Printf("%d\t", fibonacci(i))
    }
}

21.Go 语言类型转换

type_name(expression)
package main

import "fmt"

func main() {
   var sum int = 17
   var count int = 5
   var mean float32
   
   mean = float32(sum)/float32(count)
   fmt.Printf("mean 的值为: %f\n",mean)
}

22.Go 语言接口

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定义结构体 */
type struct_name struct {
   /* variables */
}

/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法实现*/
}
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()

}

23.Go 错误处理

Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
error类型是一个接口类型,这是它的定义:

type error interface {
    Error() string
}

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, errors.New("math: square root of negative number")
    }
    // 实现
}

24.Go 语言并发

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。
goroutine 语法格式:

go 函数名( 参数列表 )

package main

import (
        "fmt"
        "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}

25.实例

package main

import "fmt"

func main() {
	/* 这是我的第一个简单的程序 */

	const constvalue = "my first "
	fmt.Println("Hello, World!")
	var str string = "This is a String"
	fmt.Println(str)
	var i, j int = 1, 2
	fmt.Println(i + j)
	fmt.Println(&i)
	fmt.Println(constvalue)
	fmt.Println("-------------------")
	var a, b int = 10, 11
	if a > b {
		fmt.Println("a>n")
	} else if a == b {
		fmt.Println("a=b")
	} else {
		fmt.Println("a<b")
	}
	fmt.Println("--------------")
	var sum int = 0
	var num int = 0

	for num = 0; num < 10; num++ {
		fmt.Print("num = ")
		sum += num
		fmt.Println(num)
	}
	fmt.Println(sum)
	var l = max(a, b)
	fmt.Println(l)
	headNode := &Node{
		Data: 0,
		Next: nil,
	}
	node1 := &Node{
		Data: 1,
		Next: nil,
	}
	node2 := &Node{
		Data: 2,
		Next: nil,
	}
	node3 := &Node{
		Data: 3,
		Next: nil,
	}
	list := headNode
	Insert(node1, headNode)
	Insert(node2, headNode)
	Insert(node3, headNode)
	PrintList(list)
	fmt.Println("------------------")

	root1 := &Tree{
		data:  0,
		right: nil,
		left:  nil,
	}
	root2 := &Tree{
		data:  1,
		right: nil,
		left:  nil,
	}
	root3 := &Tree{
		data:  2,
		right: nil,
		left:  nil,
	}
	trees := root1
	add(root2, root1)
	add(root3, root1)
	display(trees)
}

func max(i, j int) int {
	if i > j {
		return i
	} else if i == j {
		return 0
	} else {
		return j
	}
}

type Node struct {
	Data int
	Next *Node
}

func Insert(node *Node, root *Node) {
	tmp := root
	for tmp.Next != nil {
		tmp = tmp.Next
	}
	tmp.Next = node

}

func PrintList(list *Node) {
	p := list
	for p != nil {
		fmt.Printf("%d ", p.Data)
		p = p.Next
	}
	fmt.Println()
}

type Tree struct {
	data  int
	right *Tree
	left  *Tree
}

func add(tree *Tree, root *Tree) {
	current := root
	for {
		root := current
		if current.data < tree.data {
			current = current.right
			if current == nil {
				root.right = tree
				break
			}
		} else {
			current = current.left
			if current == nil {
				root.left = tree
				break
			}
		}
	}

}

func display(root *Tree) {
	if root != nil {
		display(root.left)
		fmt.Println(root.data)
		display(root.right)
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值