go语言基础(二)

一、go 环境变量

1. GOROOT

GOROOT 常被描述为 Go 编译器的路径

GOROOT 不需要我们去配,一般安装 GO 编译器时选择的路径就是 GOROOT 路径

import 包时,原生 pkg 也是根据 GOROOT 来引用的
所以说使用过 npm 的同学可以理解为:全局包路径

2. GOPATH

GOPATH 常被描述为 Go 源码(工程)路径
GOPATH 需要我们去手动配置,不配也无妨,有点像 npm 的本地包路径


在特殊情况下需要批量 run,例如 go run main1.go main2.go
注: main1.go 与 main2.go 同包并属于 extension 关系
go build
编译源码,生成可执行程序;在特殊情况下需要批量编译,例如 go build main1.go main2.go

go install
编译生成项目可执行文件,默认生成在 GOPATH 目录下的 bin 目录中

二、数据类型

1、字符串

字符串是一种内置的类型,和C++中的包类似,可以使用数组下标的形式获取字符,还需要注意的是,golang中只支持UTF-8以及Unicode的编码,而对于其他的编码并没有内置的编码转换。

//截取字符串:
_str := "hello seaconch."

fmt.Println(_str[:]) -> hello seaconch.
fmt.Println(_str[7:]) -> eaconch.
fmt.Println(_str[:8]) -> hello se
fmt.Println(_str[7:8]) -> e

七牛云存储团队自己搞的一个转换的源码: https://github.com/xushiwei/go-iconv  

2、数组与切片

Go语言切片是对数组的抽象。由于Go数组的长度不可改变,Go中提供了一种灵活、功能强悍的内置类型切片("动态数组"),切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

与 c数组相比新增特性 
a. 可以使用len获得数组的长度 
b. 可以使用range来遍历访问容器中的元素,类似于foreach.例如
c. golang中的数组是值类型,和c语言中的数组名代表的是首地址不同。
   传递数组的时候,不会改变原数组中的值,并且因为是值传递,
   每次都会进行一次形参值得copy,这降低了函数调用的效率和空间的浪费。

切片在本质上是数组的视图,切片是一个数组片段的描述,
包含了指向数组的指针、片段的长度和容量(片段的最大长度)。

//创建数组切片的三种方式:
//1、基于原生数组创建
var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}  
var mySlice [ ]int = myArray[:5]  

//2、使用make直接创建
mySlice1 := make([ ]int,5)  //出事元素个数是5,且都为0
mySlice2 := make([ ]int, 5, 10)  //容量是10
mySlice3 := [ ]int{1,2,3,4,5}  //元素是1,2,3,4,5的切片。

//3、基于已有的切片进行创建
oldSlice := []int{1, 2, 3, 4, 5}
newSlice := oldSlice[:3] // 基于oldSlice的前3个元素构建新数组切片


package main
 
import "fmt"
 
func sliceOperate() {
 
   var numbers = [3]int{0,1}//数组
   s1 := numbers[1:]//切片
   s1[0] = 101//修改切片的元素的值
   printSlice(s1)//len=2 cap=2 slice=[101 0]
   fmt.Println(numbers)//[0 101 0]
 
   //向切片追加一个元素
   s1 = append(s1, 2)
   printSlice(s1)//len=3 cap=4 slice=[101 0 2]
   //向切片添加一个元素,已经超越cap,系统会为切片分配更大的底层数组
   s1 = append(s1, 3)
   printSlice(s1)//len=4 cap=4 slice=[101 0 2 3]
   fmt.Println(numbers)//[0 101 0]
 
   //同时添加多个元素,系统为切片分配新的底层数组
   s1 = append(s1, 4,5,6)
   printSlice(s1)//len=7 cap=8 slice=[101 0 2 3 4 5 6]
   fmt.Println(numbers)//[0 101 0]
 
   //创建切片numbers1,len与numbers切片相同,cap为2倍
   s2 := make([]int, len(s1), (cap(s1))*2)
   //拷贝numbers的内容到numbers1
   copy(s2,s1)
   printSlice(s2)//len=7 cap=16 slice=[101 0 2 3 4 5 6]
 
//将s2中的0删除
    s2 = append(s2[0:1], s2[2:]...)
    printSlice(s2)//len=6 cap=16 slice=[101 2 3 4 5 6]
 
//删除第一个元素
   front := s2[0]
   fmt.Println(front)//101
   s3 := s2[1:]
   printSlice(s3)//len=5 cap=15 slice=[2 3 4 5 6]
 
   //删除最后一个元素
   tail := s2[len(s2)-1]
   s4 := s2[:len(s2) - 1]
   fmt.Println(tail)//6
   printSlice(s4)//len=5 cap=16 slice=[101 2 3 4 5]
 
}
 
func main() {
   sliceOperate()
}

3、集合map

     Ma是一种无序的键值对的集合。Map最重要的一点是通过key来快速检索数据。Map是一种集合,可以对其进行迭代。Map使用hash表来实现,Map是无序的,无法决定返回顺序

a. 声明和创建,使用map,make关键词 
例如:var myMap map[string] PersonInfo = make (map[string] PersonInfo,100)

b. 初始化和赋值 
myMap = map[string] PersonInfo { 
           “1234”: PersonInfo{“1”, “Jack”, “Room 101, …”}, 
       } 
 
myMap[“1234”] = PersonInfo{“1”, “Jack”, “Room 101, …”}

c. 元素的删除 
例如:delete(myMap, “1234”);

d. 元素的查找 
例如: 
value, ok := myMap[“1234”] 
if ok { // 找到了 
// 处理找到的value 
} 
package main
 
import "fmt"
 
func mapDemo(){
   //map集合创建
   var countryCapitalMap map[string]string
   countryCapitalMap = make(map[string]string)
 
   //map插入key-value对
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "罗马"
   countryCapitalMap["Japan"] = "东京"
   countryCapitalMap["India"] = "新德里"
   //map值的修改
   countryCapitalMap["France"] = "巴黎"
 
   //输出国家首都信息
   for country := range countryCapitalMap {
      fmt.Println(country, "首都是", countryCapitalMap[country])
   }
 
   //查看元素在集合中是否存在
   captial, ok := countryCapitalMap["美国"]
   //如果确定是真实的,则存在,否则不存在
   if (ok) {
      fmt.Println("美国的首都是", captial)
   } else {
      fmt.Println("美国的首都不存在")
   }
}
 
func deleteMap(){
   //创建map
   countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"}
 
   fmt.Println("原始地图")
 
   //打印地图
   for country := range countryCapitalMap {
      fmt.Println(country, "首都是", countryCapitalMap [ country ])
   }
   //删除元素
   delete(countryCapitalMap, "France")
   fmt.Println("法国条目被删除")
   fmt.Println("删除元素后地图")
   //打印地图
   for country := range countryCapitalMap {
      fmt.Println(country, "首都是", countryCapitalMap [ country ])
   }
}

func main(){
   mapDemo()
   deleteMap()
}

 4、迭代range

range关键字用于for循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。
在数组和切片中,range返回元素的索引和索引对应的值,在集合中返回key-value对的key值。
package main
 
import "fmt"
 
func rangeDemo(){
   //使用range遍历切片
   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)
      }
   }
   fmt.Println(sum)
 
   //使用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.Printf("%d %c\n",i,c)
 
   }

   a := map[int]string{1:"hello",2:"world"}
   for k,v := range a{
   fmt.Println(k,v)
   }
}
 
func main() {
   rangeDemo()
}

5、指针

  • 指针 (Pointer) 也就是内存地址,
  • 指针变量是用来存放内存地址的变量.
  • Go 语言的取地址符是&, 返回相应变量的内存地址.
  • 空指针 (Null Pointer) 是在计算中有保留值, 用于指示指针不引用有效对象. 
  • 二级指针是一个指向一级指针值的指针.

 

package main

import "fmt"

func main() {

	// 定义变量
	var num = 10

	// 调试输出值和地址
	fmt.Println("值: ", num, "地址: ", &num)

    // 定义指针
	var pnum = &num

	// 调试输出
	fmt.Println("变量值: ", num, "变量地址: ", &num)
	fmt.Println("指针值: ", pnum, "指针地址: ", &pnum)
    
    // 通过指针改变变量的值
	*pnum = 100
	fmt.Println(num, &num)

}

三、参考

  1. Go语言内置容器
  2. go语言 指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**星光*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值