golang学习之第二天

第二天

指针

  • 一个指针变量指向了一个值的内存地址,类似于变量和常量。
  • 指针声明格式如下:
var var_name *var_type
str := new(string)
//列
var ip *int
  • 指针赋值
var a int= 20   /* 声明实际变量 */
var ip *int        /* 声明指针变量 */
  • 获取指针的值指针
/* 使用指针访问值 */
fmt.Printf("*ip 变量的值: %d\n", *ip )
  • Go 空指针
var  ptr *int
var ptr *int;
fmt.Println(ptr)
fmt.Printf("ptr 的值为 : %x\n", ptr  )
//输出: <nil>
//输出: ptr 的值为 : 0
  • 指针数组
package main

import "fmt"

const MAX int = 3

func main() {
   a := []int{10,100,200}
   var i int
   var ptr [MAX]*int;

   for  i = 0; i < MAX; i++ {
      ptr[i] = &a[i] /* 整数地址赋值给指针数组 */
   }

   for  i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
   }
}
  • 指向指针的指针
package main

import "fmt"
func main(){
    var a int = 5
    //把ptr指针 指向5所在地址
    var ptr *int = &a
    //开辟一个新的指针,指向ptr指针指向的地方
    var pts *int = ptr 
    //二级指针,指向一个地址,这个地址存储的是一级指针的地址
    var pto **int = &ptr
    //三级指针,指向一个地址,这个地址存储的是二级指针的地址,四级指针同上
    var pt3 ***int = &pto
    fmt.Println("a的地址:",&a,
        "\n 值", a, "\n\n",

        "ptr指针所在地址:",&ptr,
        "\n ptr指向的地址:",ptr,
        "\n ptr指针指向地址对应的值",*ptr,"\n\n", 

        "pts指针所在地址:",&pts,
        "\n pts指向的地址:", pts,
        "\n pts指针指向地址对应的值:",*pts,"\n\n", 

        "pto指针所在地址:",&pto,
        "\n pto指向的指针(ptr)的存储地址:",pto, 
        "\n pto指向的指针(ptr)所指向的地址: " ,*pto, 
        "\n pto最终指向的地址对应的值(a)",**pto,"\n\n",

        "pt3指针所在的地址:",&pt3,
        "\n pt3指向的指针(pto)的地址:",pt3,//等于&*pt3,
        "\n pt3指向的指针(pto)所指向的指针的(ptr)地址", *pt3, //等于&**pt3,
        "\n pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a):",**pt3, //等于&***pt3,
        "\n pt3最终指向的地址对应的值(a)", ***pt3)
}
//结果
/*
 a的地址: 0xc0000140d8 
 值 5 

 ptr指针所在地址: 0xc00000e028 
 ptr指向的地址: 0xc0000140d8 
 ptr指针指向地址对应的值 5 

 pts指针所在地址: 0xc00000e030 
 pts指向的地址: 0xc0000140d8 
 pts指针指向地址对应的值: 5 

 pto指针所在地址: 0xc00000e038 
 pto指向的指针(ptr)的存储地址: 0xc00000e028 
 pto指向的指针(ptr)所指向的地址:  0xc0000140d8 
 pto最终指向的地址对应的值(a) 5 

 pt3指针所在的地址: 0xc00000e040 
 pt3指向的指针(pto)的地址: 0xc00000e038 
 pt3指向的指针(pto)所指向的指针的(ptr)地址 0xc00000e028 
 pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a): 0xc0000140d8 
 pt3最终指向的地址对应的值(a) 5
*/
  • 总结
  1. 指针是指向值的地址
  2. 指向指针的指针是指向指针的地址

结构体

  • 示例
package main

import "fmt"

type Book struct {
   title string
   author string
   subject string
}


func main() {
    fmt.Println(createBook())
    //访问结构体成员
    fmt.Println(createBook().title)
}

// 创建一个新的结构体
func createBook() Book{

    // book := Book{"go", "ll", "编程语言"}
    var book Book

    //成员设置
    book.title = "go"
    // 忽略的字段为 0 或 空
    return book
}
  • 提示: 定义指向结构体的指针类似于其他指针变量

切片

  • Go 语言切片是对数组的抽象

  • 切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大(可以理解为动态数组)

  • 定义切片(使用make函数)

var slice1 []type = make([]type, len, capacity)//len为切片的初始长度。
var slice2 = [] int {1,2,3 } //slice2 后面不能跟类型[]中什么都不写
var slice3 =  slice2[0:2] //将slice2中从下标s0到1下的元素截取出来创建为一个新的切片,不设置分别默认0和最后一个
  • 切片函数
len(slice) //获取切片的长度
cap(slice) //获取切片的容量
slice = append(sliece, value) //向切片中添追加值,可以添加切片
copy(slice1,slice2) //拷贝 slice2 的内容到 slices1

语言范围(Range)

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

map集合

  • 定义 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 */
    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 ])
    }
}
  • map在只读的时候是线程安全的,在写的时候是线程不安全的

  • sync.Map(线程安全的map)

package main
import (
      "fmt"
      "sync"
)
func main() {
    var scene sync.Map
    // 将键值对保存到sync.Map
    scene.Store("greece", 97)
    scene.Store("london", 100)
    scene.Store("egypt", 200)
    // 从sync.Map中根据键取值
    fmt.Println(scene.Load("london"))
    // 根据键删除对应的键值对
    scene.Delete("london")
    // 遍历所有sync.Map中的键值对
    scene.Range(func(k, v interface{}) bool {
        fmt.Println("iterate:", k, v)
        return true
    })
}
  • 列表(List)
var list_nam list.List//第一种定义方式
list_name := list.New()//第二种定义方式
  • 列表与切片和 map 不同的是,列表并没有具体元素类型的限制,因此,列表的元素可以是任意类型,这既带来了便利,也引来一些问题,例如给列表中放入了一个 interface{} 类型的值,取出值后,如果要将 interface{} 转换为其他类型将会发生宕机

  • 方法

//均返回操作节点句柄
list.InsertAfter(v interface {}, mark * Element) //在 mark 点之后插入元素,mark 点由其他插入函数提供
list.InsertBefore(v interface {}, mark * Element) //在 mark 点之前插入元素,mark 点由其他插入函数提供
list.PushBackList(other *List)	//添加 other 列表元素到尾部
list.PushFrontList(other *List)	//添加 other 列表元素到头部

list.Remove(element)
  • 遍历(list是双链表,需要Front() 函数获取头元素,遍历时只要元素不为空就可以继续进行,每一次遍历都会调用元素的 Next() 函数)
l := list.New()
// 尾部添加
l.PushBack("canon")
// 头部添加
l.PushFront(67)
for i := l.Front(); i != nil; i = i.Next() {
    fmt.Println(i.Value)
}

接口

  • Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
  • 示例
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()

}
  • 注意: 接口中的方法需要被全部实现

并发

  • Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
  • 同一个程序中的所有 goroutine 共享同一个地址空间
  • 开启线程:
go func_name()

通道(channel)

  • 通道声明:
ch := make(chan int)
  • 发送值:
ch <- value
  • 接受值:
value <- ch
  • 注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。
  • 示例:
package main

import "fmt"

func sum(s []int, c chan int) {
        sum := 0
        for _, v := range s {
                sum += v
        }
        c <- sum // 把 sum 发送到通道 c
}

func main() {
        s := []int{7, 2, 8, -9, 4, 0}

        c := make(chan int) //建立通道
        go sum(s[:len(s)/2], c)
        go sum(s[len(s)/2:], c)
        x, y := <-c, <-c // 从通道 c 中接收

        fmt.Println(x, y, x+y)
}
通道缓冲区
  • 通道可以设置缓冲区,通过 make 的第二个参数指定缓冲区大小:
ch := make(chan int, 100)
  • 带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。

  • 不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了

注意:如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值