Golang自学系列

为什么会有这个系列?

因为我要往架构方向靠拢啊。
关于架构,其实架构的书我看了《架构整洁之道》,也有《实现驱动领域设计》。但是我感觉明显还不够,所以我在极客时间买了一个架构相关的专栏,这个专栏写的编程语言是 go,为了更好的学习与理解,所以才有这个系列。

我在使用vscode进行go编程时,总会显示一下警告

type Service struct {
        a *ClassName
}
exported type Service should have comment or be unexported

这是因为你安装插件 gopls 对代码会有一些规则。即如果你定一个 变量/类 时,如果开头是大写字母,那么编辑器就会检测出你没有针对这个 变量/类 进行注释。这个时候有两种选择

  1. 将大写字母改成小写字母 service
  2. 进行特定格式注释,如上面注释就是这样//Service 服务类

其实除了这个还有一种做法,直接设置vscod的相关检测的属性"go.lintFlags":["--disable=all"],这样就不用写那些烦人的注释啦。

golang 的编码习惯有个很有意思,就是它的所有变量、方法、类 等等在代码的末句全都不需要打分号,就算你打了分号,编辑器一样也会给你自动省略

怎么导入第三方库?

直接在官方仓库地址选择自己要导入的模块,地址见:https://pkg.go.dev

import ("moduleName")

但是我当初这么做的时候,发现虽然编译器没有检测到错误,但是在引用 module 的 api 时,没有智能提示。后来发现跟 nuget 是一样的,有快捷键导入 module: shift + command + p 然后选择 Go: Add Import 选中你本地 clone 下来的第三方类库。但是这里有一个疑问,难道要每次下载源代码吗?而是不能够直接下载一个类似 dll 的可执行的 “微文件” 么。讲道理是肯定有的,不可能一个项目发布出去,还把人家的源代码发不出去的。这个之后弄到发布的时候在回过头来查资料吧

错误1: expected ‘;‘, found f 这个是不同编辑器的编码问题,拿我现在用的 vscode 为例,我新建的 go 项目的默认编码是 LF/CRLF,切换成 CRLF/LF 。注意,如果切换的时候发现还是报同样的错误,那极有可能是 vscode 没有反应过来,只要在当前页面随便输个空格在保存即可。

接下来就是各种变量函数的基本用法介绍了

null 值:golong 用 nil 代表 null,这个很特别啊,大多数语言都是 null

定义类:用 type 关键字 type ClassName struct{ someField int}

申明变量:var scopeVar = "string" 我试了一下,这种显示写法也行 var scopeVar string = ""

但是有这么一种写法 localVar := "",也很有趣,我尝试了一下,这个好像只能在方法里面写(就相当于 var localVar string = ""),这种写法提升到 “全局” 则不行。

golong 具有指针概念

指针保存的是变量的内存地址。比如 var p *int p 表示的是整形的地址,其零值是 nil

这个跟 c++ 的指针是一样的,比较复杂,当时上大学的我上课上到这个地方的时候很懵,什么“指针”,“指针的引用”,“指针的指针”,“ * ”,“ & ” 等总是搞不清楚。在用 vc++ 6.0 时代下,编写代码没有任何提示,简直是难如登天。

但是现在时代不同啦,ide/编辑器 可以自动帮你做正确的选择。这次偶然的机会学习 golang,不过我还是有必要把这地方的知识弄清楚。

首先看下面代码,我把注释写在边上

var p *int  // 变量 p 代表是整形的内存地址
i := 11 // 就一般的变量赋值
p = &i  // 给内存地址指针变量 p 赋值 11 的指针变量
*p = 1  // p 地址的值赋值为 1

第二行我就不解释了。

第一行代码就是定义一个指向整形的内存地址的变量 p。

第三行代码表示你要给一个整形的地址赋值,那么肯定不是直接赋值一个整数 i,而是这个变量 i 指向的整数的地址 &i。其实可以理解为 i 的一个引用。

第四行我要直接给 p 指针指向的地址具体的值,那就是我们之前说的 “指针的指针:*p = 1”。

函数申明

函数在 golang 里面同 js 是一样 —— 一等公民。也就是你无论写在哪里,它都是可以在当前域是有效,可以引用的。

函数申明分两种

  1. 无返回值:func SomeMethod() {}

    1. 带参数:func SomeMethod(a int) {}
  2. 有返回值:func SomeMethodAndReturn() ReturnValue {}

函数这里面有个好玩的约定:

  • 函数名首字母是小写就是 private 私有方法
  • 函数名首字母是大写则是 public 共有方法

我们还可以定一个函数类(函数类就相当于 C# 的委托,委托对于 CLR 而言就是一个含有这么一个函数的类,也可以当做 Java 中的内部类处理)。实例代码如下所示

type delegateFunc func(string)  // 定一个委托
func serve(msg string){
  fmt.Printf(msg)
}
func main(){
  d := delegateFunc(serve)  // 把函数当作参数传递
  d("marson shine")
}

方法定义

方法的定义跟函数很像: func (type类型参数) MethodName(parameters) ReturnValue {}

先来看官网对方法的定义

一个 type 指定的类型可以关联方法集。一个接口类型的方法集是其接口。任何类型 T 的方法集,由它作为接收器接收所有方法。对应的指针类型 *T 的方法集是由接收器 *T 或者是 T 申明的方法集(那也就说,它包含了 T 的所有方法集)。更多的规则运用在包含那些匿名字段的结构(struct)上。任何类型都有空的方法集。在一个方法集中,每个方法必须有一个唯一的不为空的名称。

我们举个例子来说明:

func (typeName ClassName) MethodName(parameter string) string {

}

这里我们定义了一个方法,指定的接收器就是 ClassName 类型,即我们得先有个接收器,才能有这个方法集 MethodName

type ClassName struct {
        userName string
}

那么这个时候我就可以出实话一个 ClassName,然后就可以调用方法 MethodName 了。

对于上面的方法定义,其实还有一种写法是这样的:

func (typeName *ClassName) MethodName(parameter string) string {

}

这个我翻阅了下资料,发现这个还是很有趣的,这个跟编译器以及 golang 本身的 “函数式编程” 的特性有关。函数式有个很重要的特征,就是 “无状态” 的。举个例子,我新建一个函数,这个函数本身是无状态的,只要你传入的参数不变,那么这个函数得到的值就是恒定值。我们拿之前的方法为例子 func (typeName ClassName) MethodName(parameter string) string {} 这个就是说你无法更改 typeName 这个值,它是不变量的。你只能在这个函数领域下更改,一旦这个方法返回(指定的栈地址)则传入的 typeName 就还是之前的状态。如果你要像 C# 一样传递一个引用,在局部更改返回后,这个引用对象同样也会更改的话,改怎么实现呢?也很简单,只要在原来的基础之上加个 “ * ”,也就是上面的写法。

原文地址:https://www.cnblogs.com/ms27946/p/12389405.html

时间: 2024-08-03 23:07:07

Golang自学系列的相关文章

Golang 入门系列(十五)如何理解go的并发?

前面已经讲过很多Golang系列知识,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html, 接下来要说的是golang的并发,其实之前简单介绍过协程(goroutine)和管道(channel) 等基础内容,只是比较简单,只讲了基本的语法.今天就详细说说golang的并发编程. 一.并发和并行 Go是并发语言,而不是并行语言.所以我们在讨论,我们首先必须了解什么是并发,以及它与并行性有什么不同. 什么

1、认识3DSMAX(3DMAX基础自学系列)

一.关于3DSMAX的简介 3DSMAX的全称是3D Studio Max,一般简称为MAX或者3ds Max,是于Autodesk公司开发的基于PC系统的三维动画渲染和制作的软件,其前身是基于DOS操作系统的3D Studio系列软件.3DSMAX被广泛应用于广告.影视.工业设计.建筑设计.多媒体制作.游戏.辅助教学以及工程可视化等领域.   二.3DSMAX的特点 ①功能强大,扩展性好,建模功能强大,以及丰富的插件. ②操作简单,容易上手. ③与其他相关软件配合流畅. ④效果非常好 三.3D

Golang 入门系列(七)Redis的使用

安装 1. Redis 的安装很简单,我这里测试直接用的是windows 的版本.如何安装就不细说了.想了解的可以看之前的文章:https://www.cnblogs.com/zhangweizhong/category/771056.html 2. golang 客户端,用的是 go-redis, 1.   go get github.com/go-redis 2.  接着在代码中导入此包即可: import "github.com/go-redis/redis" 基本操作 创建Re

Golang 入门系列(十) mysql数据库的使用

之前,已经讲过一些Golang的基础的东西,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html, 今天简单介绍下Golang是如何使用mysql数据库的.由于Go本身不提供具体数据库驱动,只提供驱动接口和管理.各个数据库驱动需要第三方实现,并且注册到Go中的驱动管理中.github上面的mysql驱动有好几个,我在这里选择的https://github.com/go-sql-driver/mysql.

Golang 入门系列-八怎样实现定时任务,极简版.

感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53303.html 前面讲介绍了Go 语言的基础入门及Golang的语法结构.同时也介绍Golang的接口及协程等内容.感兴趣的朋友可以先看看之前的文章.接下来说一说Golang 如何实现定时任务. golang 实现定时服务很简单,只需要简单几步代码便可以完成,不需要配置繁琐的服务器,直接在代码中实现. 1.使用的包 github.com/robfig/cron 2.示例 1.创建最简单的最简单cr

Hadoop自学系列集(二) ---- CentOS下安装JDK

上篇我们讲述了如何使用VMware安装CentOS系统,接下来就看如何安装我们最为熟悉的jdk吧!安装前先看看系统上有没有安装过jdk,输入java -version,如果查询出了其他版本的jdk版本,就先删除了,笔者这里使用jdk1.6.说开始就开始,下面开始说明安装步骤吧. 1.我们去Oracle获取jdk1.6安装文件,地址分享:http://download.oracle.com/otn/java/jdk/6u45-b06/jdk-6u45-linux-i586.bin,这地址不能直接进

C#自学系列 - 开篇

2014年即将过去,这一年我参加了不少面试,被问到了很多问题.回来总结下发现自己确实在基础方面有着很多的不足,还有很多东西是我不知道的.遂在下半年购入书籍若干,并系统的加以学习.我目前在看的书是Jon Skeet的深入理解c#和精通C#第六版.老板还推荐了C#核心技术不过我还没买.精通C#这本书还是不错,涵盖的知识点非常多,所以也很厚,我不得不使用菜刀他切成四部分,否则真是无法好好的阅读下去. 11月份换了新工作,领域转向金融方面IT,使用的工具陡然高大上起来:最新的c#,.net环境,asp.

【ABAP自学系列(一)】

一.查看补丁包级别 然后看Patch Level即可. 常用T-code: SE38(写程序) SE80(屏幕开发) Smartform(开发smartform打印) SE37(可以查看function) BAPI(程序接口) SM35(录屏) ABAPDOCU(abap文档 一些开发的例子,help文档)

Golang加密系列之AES

这里我们只讨论使用aes加密算法,pkcs7padding,CBC模式模式进行加密. 加密代码: func Encrypt(plantText, key []byte) ([]byte, error) {    block, err := aes.NewCipher(key) //选择加密算法    if err != nil {       return nil, err    }    plantText = PKCS7Padding(plantText, block.BlockSize()