Golang 基礎(chǔ)知識(shí)
大家好,我叫謝偉危号,是一名程序員牧愁。
剛剛工作一年,在編程領(lǐng)域是一名小兵外莲。
對(duì)于初學(xué)者猪半,或者說自學(xué)編程的人, 我非常理解他們自學(xué)的煩惱在哪里偷线。
因?yàn)槲乙彩菑淖詫W(xué)一路過來的磨确。都會(huì)經(jīng)歷這些過程, 堅(jiān)持下去就行, 相信我, 你幷不孤獨(dú).
如果你打算走編程的道路, 第一份工作一定要你喜歡, 或者說不討厭,同時(shí)又是在編程的路上. 堅(jiān)持下去, 相信我, 你幷不孤獨(dú).
怕的是你第一份工作因?yàn)檎T惑, 走了其他路, 內(nèi)心又想編程, 這種糾糾結(jié)結(jié)的狀態(tài),會(huì)讓你過的很不舒服, 焦慮, 難以成長.
我2016年算是正式開始編程。那時(shí)小大小鬧, 不正規(guī), 怎么好玩怎么來, 學(xué)了忘, 忘了學(xué)...
我自學(xué)編程的時(shí)候都是寫一些小的示例声邦。沒資源乏奥,沒途徑了解在企業(yè)里,到底需要些什么樣的技能亥曹。于是一遍遍熟悉編程語言的特性邓了。相信自學(xué)的編程的人大都是這樣, 稍微厲害點(diǎn)的,肯琢磨的, 搞幾個(gè)項(xiàng)目, 可見的項(xiàng)目出來, 就越來越熟練.
我直到畢業(yè)后,前大半年都是在學(xué)習(xí)媳瞪,慢慢的接觸一些東西骗炉。知道企業(yè)的一般開發(fā)流程是怎樣的。企業(yè)需要什么樣的技能材失,企業(yè)需要什么的技術(shù)痕鳍。
我覺得我有必要分享出來一些企業(yè)的解決方式:
- 會(huì)用些什么
- 開發(fā)流程是什么樣的
- 需要什么樣的人
- 怎么技術(shù)選型
...
當(dāng)然這些受限于我自己的經(jīng)驗(yàn),但還是希望對(duì)大家有啟發(fā).
我的這個(gè)專欄,主要是想在自己已經(jīng)使用 Golang 大半年寫了幾千行代碼、搞過兩個(gè)完整的項(xiàng)目之后笼呆,想更精深 Golang 這門語言的語言特性熊响。
同時(shí)我正在看《代碼大全》,有必要把一些好的編程思路注意事項(xiàng)分享出來诗赌。
這是我寫這一系列文章的初衷汗茄。
在開始之前, 我再羅嗦兩句: 1. 整體統(tǒng)一的代碼風(fēng)格非常重要 2. 剛開始就堅(jiān)持一些好的編程風(fēng)格
基礎(chǔ)知識(shí)
上一節(jié)講了 Golang 環(huán)境的搭建、項(xiàng)目的組織和包管理工具 govendor铭若。
插播一個(gè)第三方下載包的工具: gopm, 這個(gè)工具解決的問題是: go get 一般是從 github 服務(wù)器, 或者 google 服務(wù)器上下載第三方庫, 所以有時(shí)候網(wǎng)速慢,或者下載不成功.
地址: gopm
下載 gopm:
go get -u github.com/gpmgo/gopm
再使用 gopm 下載第三方庫:
gopm get -g -v ****
這一節(jié)講 Golang 的基礎(chǔ)知識(shí)洪碳。主要包括:
- 變量
- 常量
- 字符串
- 數(shù)組
- 切片
- Map
- 結(jié)構(gòu)體
- 函數(shù)
- 方法
- 分支
- 循環(huán)
這些內(nèi)容的熟悉就能開始寫代碼了。
編程和寫作類似叼屠,這些基礎(chǔ)知識(shí)就相當(dāng)于寫作中的文字瞳腌。但為什么不同的人寫的代碼、文章存在很大的差異镜雨,有些人寫的好嫂侍,有些人寫的不好。
這其實(shí)是代碼的組織或者的文字的組織荚坞。
初學(xué)者往往不太注意這些:
比如:
- 不太注意變量的命名
- 不太注意函數(shù)的命名
- 不太注意函數(shù)的組織方式
- 不太注意項(xiàng)目的組織(即:代碼文件的組織)
- 不太注意整體的布局風(fēng)格
那他們在注意什么? 注意實(shí)現(xiàn), 一定程度上實(shí)現(xiàn)能促進(jìn)初學(xué)者學(xué)習(xí)的熱情. 相信我, 這些不注意,往往到最后會(huì)成為你的阻礙.
寫代碼挑宠,最后雖然是計(jì)算機(jī)執(zhí)行,但是終歸是人的產(chǎn)品颓影,由人來閱讀各淀。
除非你對(duì)自己的編程水平很有信心,否則這些原則需要堅(jiān)持诡挂。能不抽象就不抽象碎浇。做到“望文生義”,即看到你的代碼大概就知道你想要干嘛璃俗,你的函數(shù)想要實(shí)現(xiàn)什么樣的功能南捂,你的項(xiàng)目想要實(shí)現(xiàn)什么樣的功能。
這一點(diǎn)旧找,其實(shí)之前我也不是太注意溺健。最近不是在閱讀《代碼大全》嘛。
寫一些代碼片段可能不太能感受到這些原則能有什么樣的益處钮蛛。一旦你的項(xiàng)目越來越復(fù)雜的時(shí)候鞭缭,你別頭疼。
1 變量
變量的注意事項(xiàng)有下面幾點(diǎn):
- 命名:
原則:
- 見文知意
- 規(guī)范:Golang 中采用駝峰式標(biāo)準(zhǔn):numberOfClass
- 首字母大寫:外部可訪問魏颓;首字母小寫:內(nèi)部訪問
- 長度適中
- 避免使用關(guān)鍵字
var ok bool
var value string
var number int
- 聲明及初始化
原則:
- 明確數(shù)據(jù)類型
- 少使用隱式聲明
# Better
var Name string
# No Good
Name := "xieWei"
在函數(shù)內(nèi)部可以使用 :=
初始化岭辣,自動(dòng)判斷變量的類型。但是建議使用顯式聲明
- 使用
原則:
- 變量聲明甸饱,靠近使用處: 即你需要使用變量就在要使用的地方聲明變量沦童,而不是提前聲明一大堆仑濒,或者遠(yuǎn)離使用變量的地方,不利于閱讀
- 多個(gè)變量聲明放一起
var (
url string
result []byte
err error
)
url = "http://www.baidu.com"
if result, err = http.Get(url); err!=nil{
// do something
}
常用的布爾值變量名稱:
- done
- found
- ok
- success
- flag
使用對(duì)仗:
- begin/start
- first/last
- locked/unlocked
- min/max
- next/previous
- old/new
- opened/closed
- visible/invisible
- source/target
- source/destination
- up/down
2 常量
常量注意這幾點(diǎn):
- 關(guān)鍵字:const
const AppName = "App"
3 字符串
- 短的
var Help string
Help = "Thank you for Your help."
- 長的
var HelpMessage string
HelpMessage = `
Hello Everone:
Welcome to here.
Today, we will learn how to learn golang.
`
字符串常用的操作:
庫: strings
內(nèi)置庫的使用注意兩點(diǎn):
函數(shù)的輸入值及類型
函數(shù)的輸出值及類型
Contains
: 判斷是否包含字符串
func Contains(s, substr string) bool
-
Count
: 輸出字符串中自字符的個(gè)數(shù)
func Count(s, sep string) int
-
Index
: 返回字符第一次出現(xiàn)的位置偷遗,不存在返回 -1
func Index(s, sep string) int
-
Join
: 按給定的分隔符拼接一個(gè)字符串切片成字符串
func Join(a []string, sep string) string
-
LastIndex
: 子串最后一次出現(xiàn)的位置
func LastIndex(s, sep string) int
-
ToLower
: 將字符串全部小寫
func ToLower(s string) string
-
ToUpper
: 將字符串全部大寫
func ToUpper(s string) string
-
Repeat
: 重復(fù)字符串
func Repeat(s string, count int ) string
-
Replace
: 替換
func Replace(s, old, new string, n int) string
-
TrimSpace
: 去除字符串前後空格
func TrimSpace(s string) string
-
Split
: 切割
func Split(s, sep string) []string
4 數(shù)組
固定長度列表在Golang 里稱之為數(shù)組.
長度不固定的里稱之為切片.
var NumberList = [3]string
NumberList = [3]string{"Python", "Golang", "Java"}
- 獲取數(shù)組長度:
len
- 獲取數(shù)組容量:
cap
編程中,凡是可以使用if...else
的都可以使用數(shù)組來遍歷,再對(duì)遍歷的值進(jìn)行操作.
5. 切片
相當(dāng)于不固定長的數(shù)組. 可以初始設(shè)置容量, 超過容量后,自動(dòng)擴(kuò)充.
- len 獲取長度
- cap 獲取容量
常用的操作:
- slice
func main(){
var (
value []string
)
value = []string{
"xieWei",
"weiWei",
"wuWei",
}
fmt.Print(value[1:])
}
>>> [weiWei wuWei]
- append
func main(){
var (
value []string
)
value = []string{
"xieWei",
"weiWei",
"wuWei",
}
value = append(value, "shenWei")
fmt.Println(value)
}
>>> [xieWei weiWei wuWei shenWei]
- range 操作
func main(){
var (
value []string
)
value = []string{
"xieWei",
"weiWei",
"wuWei",
}
for index, i:= range value{
fmt.Println(index, i)
}
}
>>>
0 xieWei
1 weiWei
2 wuWei
6. Map
字典: 鍵值型
- 聲明
func mapDeclare(key string, value string)map[string]interface{}{
var (
body map[string]interface{}
)
body = make(map[string]interface{})
body[key] = value
return body
}
func main(){
fmt.Println(mapDeclare("name", "xieWei"))
}
>>> map[name:xieWei]
- 遍歷
func main(){
var (
body map[string]interface{}
)
body = make(map[string]interface{})
body["name"] = "xiewei"
body["age"] = 26
body["university"] = "shanghaiUniversity"
rangeMap(body)
}
func rangeMap(body map[string]interface{}) {
for key, value := range body{
fmt.Println(key, value)
}
}
>>>
name xiewei
age 26
university shanghaiUniversity
7. 結(jié)構(gòu)體
結(jié)構(gòu)體在 Golang 里面的作用非常大
- 即是數(shù)據(jù)類型
- 又可以有方法
作用相當(dāng)于其他語言的類.
- 聲明
type MyExample struct {
Name string
Age int
School string
}
func declare(){
var (
exampleStruct MyExample
)
exampleStruct.Name = "xieWei"
exampleStruct.Age = 26
exampleStruct.School = "shanghaiUniversity"
fmt.Println(exampleStruct)
}
func main(){
declare()
}
>>>
{xieWei 26 shanghaiUniversity}
- 方法:
值傳遞 一般獲取值: func (m MyExample) GetAttrName()string
指針傳遞一般改變值: func (m *MyExample) SetAttrAge(newAge int)
type MyExample struct {
Name string
Age int
School string
}
func declare() MyExample {
var (
example MyExample
)
example.Name = "xieWei"
example.Age = 26
example.School = "shanghaiUniversity"
fmt.Println(example)
return example
}
func (m MyExample) GetAttrName()string{
return m.Name
}
func (m *MyExample) SetAttrAge(newAge int){
m.Age = newAge
}
func main(){
test := declare()
fmt.Println(test.GetAttrName())
fmt.Println(test)
test.SetAttrAge(18)
fmt.Println(test)
}
>>>
{xieWei 26 shanghaiUniversity}
xieWei
{xieWei 26 shanghaiUniversity}
{xieWei 18 shanghaiUniversity}
- 匿名字段
即隱式的引入一個(gè)結(jié)構(gòu)體的所有字段
type MyExample struct {
Name string
Age int
School string
}
type OtherExample struct {
MyExample
}
OtherExample 自動(dòng)擁有 Name, Age, School 字段
8 函數(shù)
函數(shù)分為這麼幾類:
- 匿名函數(shù)
- 結(jié)構(gòu)體的方法
- 普通函數(shù)
要寫好函數(shù)注意下面幾點(diǎn):
- 函數(shù)名稱: 見文知意
- 參數(shù)
- 返回值
- 匿名函數(shù): 即沒有名稱的函數(shù), 字面意思, 一般用來處理簡單的函數(shù)
func main(){
var NoNameFunc = func(name string) {fmt.Println(name)}
NoNameFunc("xiewei")
}
- 普通函數(shù)
func GetMaxNumber(number float64, other float64) float64 {
return math.Max(number, other)
}
- func 關(guān)鍵字
- GetMaxNumber 函數(shù)名稱
- number, other 參數(shù) 類型 float64
- 返回值類型 float64
9 分支/判斷/循環(huán)
- if 判斷
- if ...else / switch 分支
- for 循環(huán)