热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

go之初识

1.数组的特点:声明数组时需要指定内部存储的数据的类型和存储的元素的数量,一旦声明数组里存储的数据类型和数组长度就都不能改变了。声明数组:vararray1[5]string声明并

1.数组的特点:声明数组时需要指定内部存储的数据的类型和存储的元素的数量,一旦声明数组里存储的数据类型和数组长度就都不能改变了。
声明数组:var array1 [5]string
声明并初始化数组:var array2 = [5]string{"red", "blue", "green", "yellow", "pink"}
具体值初始化数组:var array2 := [5]string{“red”, “blue”, “green”, “yellow”, “pink”}
数组赋值(相互拷贝):array1 = array2
在函数间传递数组(传地址):foo(&array1)
2.切片的特点:围绕动态数组的概念构建可以按需自动增长和缩小
make创建切片:slice := make([]string, 5, 10)
使用切片字面量来创建切片:slice := []string{“red”, “blue”, “green”}
使用切片创建切片:newslice := slice[1:2]
增加切片的容量:newslice = append(newslice, 10)
迭代切片:for index, value := range slice { }
函数间传递切片(传值):foo(slice)
3 映射的特点:用来存储一系列无序的键值对,能够基于键快速检索数据
创建映射:colors := map[string]string{“red”: “1379” }
迭代映射:for key, value := range colors { }
删除键值:delete(colors, “red”)
函数间传递映射(传值)
4 类型系统
4.1 用户定义的类型
声明一个结构类型 : type user struct{
                    name string
                    email string
                }
Go语言是一种静态类型的编程语言,编译器需要在编译时知晓程序里每一个值的类型
4.2 方法
方法:给用户定义的类型添加新的行为.     

1)使用指针接收者实现一个方法时,这个方法会共享调用方法时接收者所指向的值
指针接收:func (u *user) notify() { }  
使用指针接收者声明:bill := &user{“bill”, “[email protected]”} 
 
2)使用值接收者实现一个方法时,调用时会使用这个值的一个副本来执行
值接收: func (u user) notify() { }
使用值接收者声明:bill := user{“bill”, “[email protected]”} 
使用指针接收者声明:bill := &user{“bill”, “[email protected]”} 

总结:值接收者使用值的副本来调用方法,而指针接收者使用实际值来调用方法

4.3 类型的本质
如果给一个类型增加或者删除某个值,是要创建一个新值,还是要更改当前的值?如果是要创建一个新值,该类型的方法就使用值接收者。如果是要修改当前值,就使用指针接收者。
1)内置类型 如数值类型,字符串类型和布尔类型本质上是原始的类型,因此,当对这些值进行增加或者删除的时候会创建一个新值。
2)引用类型:切片,映射,通道,接口和函数类型
3)结构类型可以用来描述一组数据值,这组值的本质即可以是原始的,也可以是非原始的
4)是使用值接收者还是指针接收者,不应该由该方法是否修改了接收到的值来决定,这个决策应该基于该类型的本质。
4.4 接口
    接口是用来定义行为的类型。这些被定义的行为不由接口直接实现,而是通过方法由用户定义的类型实现。如果用户定义的类型实现了某个接口类型声明的一组方法,那么这个用户定义的类型的值就可以副给这个接口类型的值。这个赋值会把用户定义的类型的值存入接口类型的值。对接口值方法的调用会执行接口值里存储的用户定义的类型的值对应的方法。因为任何用户定义的elixir都可以实现任何接口,所以对接口值方法的调用自然就是一种多态。在这个关系里,用户定义的类型通常叫作实体类型,原因是如果离开内部存储的用户定义的类型的值的实现,接口值并没有具体的行为。
1)实现
与实体值赋值相比类型信息会存储一个指向保存的类型的指针而不是类型本身,而接口值第二个字依旧保存指向实体值的指针
2)方法集

(1)问题代码
go之初识
运行结果:

go之初识

要了解用指针接收者来实现接口时为什么user类型的值无法实现该接口,需要先了解方法集。方法集定义了一组关联到给定类型的值或者指针的方法。定义方法时使用的接收者的类型决定了这个方法是关联到值,还是关联到指针,还是两者都关联
3)多态
代码:
因为sendNotification接受notifier类型的接口值,所以这个函数可以同时执行user和admin实现的行为
go之初识
运行结果:
go之初识
4)嵌入类型
Go语言允许用户扩展或者修改已有类型的行为。这个功能对代码复用很重要,在修改已有类型以符合新类型的时候也很重要。这个功能是通过嵌入类型完成的。嵌入类型是将已有的类型直接声明在新的结构类型里。被嵌入的类型被称为新的外部类型的内部类型。

代码:
可以直接访问内部类型的方法ad.user.notify()
内部类型的方法也被提升到外部类型ad.notify()
go之初识
运行结果:
go之初识
(1)如果外部类型并不需要使用内部类型的实现,而想要使用自己的一套实现,我们只需要实现外部类型值的指针调用方法。如果要访问内部类型可以使用直接访问内部类型的方法ad.user.notify(),访问外部类型的方法使用ad.notify()

5 并发

1)go语言里的并发指的是能让某个函数独立于其他函数的运行能力。当一个函数创建为goroutine时,go会将其视为一个独立的工作单元。这个单元会被调度到可用的逻辑处理器上执行。

代码:
var wg sync.WaitGroup 是一个计数信号量,可以用来记录并维护运行的goroutine
wg.Add(2)表示要等待两个goroutine
wg.Done()用来通知main函数工作已经完成
wg.Wait()大于0时阻塞
go之初识
运行结果:
go之初识

在知道了如何创建goroutine,并了解了背后发生的事情了,下面要了解一下写并发程序时的潜在危险,以及需要注意的事情。
2)竞争状态
如果两个或者多个goroutine在没有互相同步的情况下,访问某个共享资源,并试图同时读和写这个资源,就处于相互竞争的状态,这种情况被称为竞争状态
3)锁住共享资源
Go语言提供了传统的同步goroutine的机制,就是对共享资源加锁。atomic包里的几个函数 与 sync包里的mutex类型 
(1)atomic.AddInt64(&counter, 1)
(2)互斥锁(mutex)
代码:
go之初识
运行结果:
go之初识
4)通道
当一个资源需要在goroutine之间共享时,通道在goroutine之间架起了一个通道,并提供了确保同步交换数据的机制。声明通道时,需要指定将要被共享的数据类型。可以通过通道共享内置类型,命名类型,结构类型和引用类型的值或者指针。
(1)使用make创建通道
无缓冲
unbuffer := make(chan int)
有缓冲
buffer := make(chan string, 10)
通过通道发送一个字符串
buffered <- “gopher”
从通道接收一个字符串
value := <-buffered
代码:
go之初识
运行结果:
go之初识


推荐阅读
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 2.2 组件间父子通信机制详解
    2.2 组件间父子通信机制详解 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 深入解析 Synchronized 锁的升级机制及其在并发编程中的应用
    深入解析 Synchronized 锁的升级机制及其在并发编程中的应用 ... [详细]
  • Python 序列图分割与可视化编程入门教程
    本文介绍了如何使用 Python 进行序列图的快速分割与可视化。通过一个实际案例,详细展示了从需求分析到代码实现的全过程。具体包括如何读取序列图数据、应用分割算法以及利用可视化库生成直观的图表,帮助非编程背景的用户也能轻松上手。 ... [详细]
  • Java并发机制详解及其在数据安全性保障中的应用方案 ... [详细]
  • 深入解析CAS机制:全面替代传统锁的底层原理与应用
    本文深入探讨了CAS(Compare-and-Swap)机制,分析了其作为传统锁的替代方案在并发控制中的优势与原理。CAS通过原子操作确保数据的一致性,避免了传统锁带来的性能瓶颈和死锁问题。文章详细解析了CAS的工作机制,并结合实际应用场景,展示了其在高并发环境下的高效性和可靠性。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 在Linux系统中,通过使用`read`和`write`函数可以实现文件的高效复制操作。`open`函数用于打开或创建文件,其返回值为文件描述符,成功时返回一个有效的文件描述符,失败时返回-1。`path`参数指定了要操作的文件路径,而`oflag`参数则定义了文件的打开模式和属性。此外,为了确保数据的完整性和一致性,还需要合理处理文件读取和写入过程中的错误和异常情况。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
author-avatar
汉臣Y
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有