go语言中的if和其他语言中的if基本一样,go语言的if语句中的条件判断不需要用括号括起来。

猜数字游戏:

1
2
3
4
5
6
7
8
9
var num int
fmt.Scanf("%d", &num)
if num < 10 {
fmt.Println("小了!")
} else if num == 10 {
fmt.Println("猜中了!")
} else {
fmt.Println("大了!")
}

输出:

1
2
3
4
5
6
7
8
9
10
11
// 输入5
5
小了!

// 输入20
20
大了!

// 输入10
10
猜中了!
阅读全文 »

代码块

go语言允许我们在很多地方定义变量,这些发生定义行为的地方可以称为代码块。

宇宙块(universe block ):包含程序中的全部代码。

包代码块(package block):go语言中一个文件夹就是一个包。简单理解就是文件夹下各个文件中代码的集合。我们可以用import来导包。

文件代码块(file block):单个文件中的代码集合。

阅读全文 »

如果我们要把一组数据组合在一起就需要用到struct了,go语言中结构体有些类似于其他语言中的class,但又很不一样,go语言不支持继承,go语言通过组合来实现类似于继承的效果。

结构体的声明定义使用

可以这样定义一个struct

1
2
3
4
type Point struct {
X int
Y int
}

一旦定义好了结构体,我们就可以声明使用这个结构体的变量了。

阅读全文 »

go语言针对数据映射的情况原生提供了map数据类型,可以这样定义一个map:map[键类型]值类型。

map的定义声明

直接用var定义的map是nil的map,其值为nil。对nil的map进行读操作总是会返回对应的零值,进行写操作会导致panic。

1
var m map[string]int

所以如果想要使用map,就不能使用值为nil的map。

阅读全文 »

在了解了切片(slice)后我们再回过头来看看字符串的切片操作。

字符串(string)的底层是一系列字节(byte),这些字节没有默认的编码,但go语言中的for range循环以及很多库函数会默认字符串是以UTF-8编码的。

可以通过[]来获取字符串指定索引处的字节值。

1
2
3
4
var a string = "Hello World!"
var b byte = a[6]
fmt.Printf("integer: %v\n", b)
fmt.Printf("character: %c\n", b)

输出:

阅读全文 »

上一篇借助qemu虚拟机实现了armhf和arm64架构的原生平台的程序编译。虽然它稳定好用,但有一个致命的缺点,特别慢。

同样的代码编译x86_64平台windows和linux的程序只需不到1分钟,而借助虚拟机编译armhf和arm64平台linux的程序要十多分钟。

于是我花了两天时间摸索交叉编译的方法,最终实现了对armhf和arm64架构的linux程序、amd64架构的windows程序、以及mac amd64和mac arm64架构的程序在amd64架构的linux下的交叉编译,算是实现了当前全部主流平台下调用gocv库的程序的交叉编译。

为了方便使用,我还是通过docker镜像来管理编译环境。

交叉编译最困难的地方在于相关的资料太少了,需要自己一点一点尝试。下面我展示一下这几个环境交叉编译的Dockerfile,大家沿着相应的思路就能实现其他程序的交叉编译了。

阅读全文 »

平时在写go程序过程中难免会写一些调用c/c++库的程序,go语言结合c/c++的代码在编译时往往非常令人头痛。下面以gocv库为例讲一下如何借助docker和qemu实现arm编译环境的搭建。

go语言原生支持交叉编译,但因为在程序中使用了gocv库,需要实现cgo的交叉编译。这一部分我实现了两种编译方式。第一种是通过虚拟机实现原生编译,第二种是配置交叉编译,本文我们讲一下借助docker和qemu实现的虚拟机容器原生编译,下一篇文章来讲交叉编译。

gocv对opencv进行了一次封装,所以如果想要编译arm版的程序,那必须搞定arm版的opencv库的编译。

采用docker+qemu搭建编译环境的原理是这样的:qemu项目中有一个qemu-user-static子项目https://github.com/multiarch/qemu-user-static 它可以实现让我们在x86_64架构的机器上通过qemu虚拟机来运行其他架构的容器。这样只要在这个虚拟机里把opencv编译好那就可以实现对应架构程序的原生编译了。本方法只有一个缺点:慢!

首先是注册qemu-user-static:

阅读全文 »

最近在写一个需要前后端保持通信的服务。前端要能及时感知后端数据的变化,后端要及时处理前端发过来的指令。这种服务就需要用到websocket了。

以前在写websocket相关的程序时,一直在用gorilla/websocket这个库,这个库事实上已经成为了go语言开发websocket应用的基础库了,不过它提供的功能比较有限,各种基本的功能,心跳等都要自己补充完善。最近这个库因找不到接手的维护人员而停止维护了。

这一两年有很多go语言的代码库停止维护了,这算是go语言相比其他语言的一个比较大的风险吧,大量go语言代码库是由为爱发电的开发者自行维护的,很多使用量非常高的库其核心开发人员只有一两个人。这些库的代码质量,维护周期都由其开发者来决定,没有回报的事情往往是做不长远的。

因为自己并不是很熟悉websocket,之前写websocket的程序时都是把例子改一改实现自己想要的功能就结束了。这次在编写调试的过程中发现了很多问题,gorilla/websocket太基础了不能满足我的需求,这促使我寻找更易用的websocket库。

我找到了两个比较好用的库,一个是melody,另一个是GoWebsocket。它们目前都还保持着更新,都是基于gorilla/websocket库的更上层的库,其中melody是服务端的库,GoWebsocket是客户端的库。

阅读全文 »

上一篇详细讲解了命令,这回我们一起来看一下Webview。vscode的插件其实可以分为两种,一种是webview插件,另一种是非webview插件。

webview插件的自由度很高,可以满足开发者的各种定制化的要求;而非webview插件只能使用vscode提供的api及ui,只适合开发简单的插件。

官方的教程:https://code.visualstudio.com/api/extension-guides/webview

vscode的webview插件的开发方式和前端开发中的iframe很像,如果把插件想像成宿主页的话,那webview就是用iframe嵌入的页面,可以通过postMessage来与插件进行信息传递。

webview可以渲染几乎所有的html元素。因此在开发插件的时候我们可以把它当成一个前端项目来开发。

阅读全文 »
0%