前言
之前在时光机里说到想在寒假学GOLANG,结果寒假变成了两个月,在开学前终于打算开始学习了。
其实之前已经借过一本GO的书《GO语言核心编程》,感觉写的挺不错的。
之所以想学GO,是因为一个RSS机器人项目flowerss-bot,采用GO编写,一份源码可以编译成多平台的可执行文件,让我很心动,这样我也可以写一个挂在VPS上了。
2020.3.24晚正式开始,之前已经把环境搭好了,所以可以直接开工。以TelegramBot为切入点开始学习
开发项目
- TG 翻译机器人 https://github.com/iyear/TranslateBot
- TG OfficeE5续订机器人 https://github.com/iyear/E5SubBot
过程
由于之前经常用的是易语言,源代码为二进制文件,不适合Git操作。这次终于可以开始学习Git了
目前对Git的印象只限于add,commit,push……不过似乎暂时够用,先这么着吧
问题汇总
go get全部在src里,import出错显示不存在
问题彻底解决,感谢v2ex大佬的文章:https://liujiacai.net/blog/2019/10/24/go-modules/
(依旧不太清楚,求大佬解答)
之前不知道为什么运行完go get,telebot就出现在了src里,当然也能用。后来用到gjson的时候go get什么反应都没有,import的时候出错,这个问题耗了很久
现在GO的包管理已经是go mod(1.11开始),但在网上搜索到的都还是老版本的方法,所以没法用
Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:
- auto:只要项目包含了 go.mod 文件的话启用 Go modules,目前在 Go1.11 至 Go1.14 中仍然是默认值。
- on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
- off:禁用 Go modules,不推荐设置。
而我的GO111MODULE为auto,但我也没有创建go.mod,所以并没有启用gomod。
后来各种瞎折腾,在目录下创建了一个go.mod然后一切就恢复正常了
Goland Git设置
Github上创建好项目,回到项目目录
VCS->导入到版本控制->创建Git仓库
右键Git项目目录,Git->Add->Commit Git->RE->Push
如果Push rejected ,貌似是因为Github上的时间线和本地不同,先同步Github,再Push
如果名字错误,进入.git->config加入
[user]
name = xxx
email = xxx@gmail.com
跨平台编译
简单方法:https://juejin.im/post/5cd9842951882568cc480199
SET CGO_ENABLED=0 SET GOOS=darwin SET GOARCH=amd64 go build test.go
SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build test.go
GOOS: darwin freebsd linux windows android dragonfly netbsd openbsd plan9 solaris
GOARCH: arm arm64(64位) 386(32位) amd64(64位) ppc64 ppc64le mips64 mips64le s390x
commit规范
参考阮一峰博客:<https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html
Screen命令
screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
删除Github上的Commit
git rebase -i "commit id"
git push origin master -f
int64,int,string互转
#string到int
int,err := strconv.Atoi(string)
#string到int64
int64, err := strconv.ParseInt(string, 10, 64)
//第二个参数为基数(2~36),
//第三个参数位大小表示期望转换的结果类型,其值可以为0, 8, 16, 32和64,
//分别对应 int, int8, int16, int32和int64
#int到string
string := strconv.Itoa(int)
//等价于
string := strconv.FormatInt(int64(int),10)
#int64到string
string := strconv.FormatInt(int64,10)
//第二个参数为基数,可选2~36
//对于无符号整形,可以使用FormatUint(i uint64, base int)
#float到string
string := strconv.FormatFloat(float32,'E',-1,32)
string := strconv.FormatFloat(float64,'E',-1,64)
// 'b' (-ddddp±ddd,二进制指数)
// 'e' (-d.dddde±dd,十进制指数)
// 'E' (-d.ddddE±dd,十进制指数)
// 'f' (-ddd.dddd,没有指数)
// 'g' ('e':大指数,'f':其它情况)
// 'G' ('E':大指数,'f':其它情况)
#string到float64
float,err := strconv.ParseFloat(string,64)
#string到float32
float,err := strconv.ParseFloat(string,32)
#int到int64
int64_ := int64(1234)
map在赋值等操作前要先初始化
var m1 map[string]string
// 再使用make函数创建一个非nil的map,nil map不能赋值
m1 = make(map[string]string)
// 最后给已声明的map赋值
m1["a"] = "aa"
m1["b"] = "bb"
// 直接创建
m2 := make(map[string]string)
// 然后赋值
m2["a"] = "aa"
m2["b"] = "bb"
获取URL的参数值
func GetURLValue(Url, key string) string {
u, _ := url.Parse(Url)
query := u.Query()
//fmt.Println(query.Get(key))
return query.Get(key)
}
取文本中间
func GetBetweenStr(str, start, end string) string {
n := strings.Index(str, start)
if n == -1 {
n = 0
} else {
n = n + len(start)
}
str = string([]byte(str)[n:])
m := strings.Index(str, end)
if m == -1 {
m = len(str)
}
str = string([]byte(str)[:m])
return str
}
判断文件是否存在
func FileExist(Path string) bool {
if _, err := os.Stat(Path); err != nil {
if os.IsNotExist(err) {
return false
} else {
CheckErr(err)
}
}
return true
}
使用sqlite数据库
只需要加载驱动的init函数即可,其他就和自带sql库一模一样了
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
定时器timer和ticker的区别
ticker只要定义完成,从此刻开始计时,不需要任何其他的操作,每隔固定时间都会触发。
timer定时器,是到固定时间后会执行一次
如果timer定时器要每隔间隔的时间执行,实现ticker的效果,使用 func (t *Timer) Reset(d Duration) bool转自链接:https://learnku.com/articles/23578/the-difference-between-go-timer-and-ticker
这也太轻强了,才高中吗。。