- I/O小练习
package main
import (
"fmt"
"os"
"reflect"
)
// 定义一个Data结构体
type Data struct {
}
// 声明Data结构体的成员函数String()
func (self Data) String() string {
return "data"
}
func main() {
fmt.Println("Hello World!")
// 格式化浮点数(转换成字符串)
str := fmt.Sprintf("%f", 3.14159)
fmt.Println(reflect.TypeOf(str))
fmt.Println(str)
// 向屏幕输出"A\n"
fmt.Fprint(os.Stdout, "A\n")
// %v智能识别输出数据的类型
fmt.Printf("%v\n", Data{}) // 实例化结构体,将自动调用String()接口,相当于java的toString()方法
}
- 字符串练习
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
str := "hello World"
//包含
fmt.Println(strings.Contains(str, "hello"), strings.Contains(str, "?"))
// 获取某个字符的索引
fmt.Println(strings.Index(str, "o"))
// 判断某个字符串的前缀和后缀
fmt.Println(strings.HasPrefix(str, "he"), strings.HasSuffix(str, "ld"))
// 字符串切割
ss := "1#2#3456"
splitedStr := strings.Split(ss, "#")
fmt.Println(splitedStr) // 返回一个字符串数组
fmt.Println(strings.Join(splitedStr, "#")) // 用#合并字符串
// 整型转化为字符串
fmt.Println(strconv.Itoa(20))
// 字符串转化成整型,返回值为(int, error)
fmt.Println(strconv.Atoi("711"))
// 将一个字符串解析成bool类型,返回值为(bool, error)
fmt.Println(strconv.ParseBool("false"))
// 将一个字符串解析成浮点数,参数列表有2个:(s string, bitSize int) 返回值为(float64, error)
fmt.Println(strconv.ParseFloat("3.014", 64)) // 第二个参数不写--->默认转换为64位浮点数
// 格式化判断语句,参数列表(b bool) 返回值为string
fmt.Println(strconv.FormatBool(0 < 1))
// 参数列表为(i int64, base int) 返回值为string
fmt.Println(strconv.FormatInt(123, 2)) // 将10进制数转换成二进制数
}
XML编码处理
- struct对象的序列化和反序列化:
package main
import (
"encoding/xml"
"fmt"
)
// 类名首字母大写,遵循驼峰命名法
type Person struct {
Name string `xml:",attr"` // 属性名首字母大写,将Name转换成tag标签的一种属性
Age int `xml:"Age"` // 自定义标签名
}
func main() {
// 序列化结构体
p1 := Person{Name: "Tony", Age: 18}
// Marshal函数的返回值为([]byte, error)
// if data, err := xml.Marshal(p1); err != nil {
// fmt.Println(err)
// return
// } else {
// fmt.Println(string(data)) // 序列化成为xml的一个流
// }
// 格式化输出:MarshalIndent函数参数列表为(v interface{}, prefix(前缀), indent string(缩进)) 返回值为([]byte, error)
var data []byte
var err error
if data, err = xml.MarshalIndent(p1, "", " "); err != nil {
fmt.Println(err)
return
}
fmt.Println(string(data)) // 序列化成为xml的一个流
// 将xml解析反序列化成结构体实例
// 先new一个Person结构体类型
p2 := new(Person)
// Unmarshal参数列表:(data []byte, v interface{}) 返回值为error
if err = xml.Unmarshal(data, p2); err != nil {
fmt.Println(err)
return
}
fmt.Println(p2)
}
- 使用
os.Args
获取简单参数
package main
import (
"fmt"
"os"
)
func main() {
// var Args []string,返回一个字符串数组
fmt.Println(os.Args)
}
命令行参数
Go语言命名规范
命名规则:
1、 golang的变量
、函数命名
需要使用驼峰命名法
,且不能出现下划线
,文件名使用下划线
。
2、golang中根据首字母的大小写
来确定访问权限
。无论是方法名
、常量
、变量名
还是结构体的名称
,若首字母大写
,则可被其他的包
访问;若首字母小写
,则只能在本包中使用。通俗地讲,首字母大写是公有的
,首字母小写是私有的
。文件的命名
:全小写
。测试的文件
:xxx_test.go中的包名
和文件夹名
最好相同。
变量命名规则
1、变量名
命名必须清晰、明了,有明确含义的单词,命名中禁止使用缩写,除非已是业界通用或标准化的缩写;
2、单字母名称
仅适用于短方法中的局部变量
,名称长短应与其作用域相对应。若变量或常量可能在代码中多处使用,则应赋其以便于搜索的名称且有意义的名称。
3、变量名一般遵循驼峰命名法
,但遇到特有名词
时,需要遵循以下规则:如果为私有变量,且特有名词为首个单词,则使用小写
,如 apiClient,其它情况都应使用该名词原有的写法
,如APIClient、repoID、UserID
错误示例:UrlArray,应该写成urlArray或者URLArray!
一些常见的特有名词:
// A GonicMapper that contains a list of common initialisms taken from golang/lint
var LintGonicMapper = GonicMapper{
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SSH": true,
"TLS": true,
"TTL": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XSRF": true,
"XSS": true,
}
函数命名规则
- 驼峰式命名,名字可以长但是得把功能,必要的参数描述清楚,函数名应当是
动词
或动词短语
,如postPayment、deletePage、save。并按Javabean标准加上get、set、is前缀。例如:xxx + With + 需要的参数名 + And + 需要的参数名 + …..
结构体命名规则
1、结构体名
应该是名词
或名词短语
,如Custome、WikiPage、Account、AddressParser,WriteDbMgr,ConfMgr,避免使用Manager、Processor、Data、Info等类名,而且类名不应当是动词
。
2、结构体中属性名大写
,如果属性名小写
则在数据解析(如json解析,或将结构体作为请求或访问参数)时无法解析
!
包名命名规则
- 包名应该为
小写单词
,不要使用下划线
或者混合大小写
。
接口命名规则
-
单个函数的接口名
以er
作为后缀,如Reader
,Writer
。接口的实现则去掉er
。
type Reader interface {
Read(p []byte) (n int, err error)
}
- 两个函数的接口名综合两个函数名
type WriteFlusher interface {
Write([]byte) (int, error)
Flush() error
}
- 三个以上函数的接口名,
抽象这个接口的功能
,类似于结构体名
type Car interface {
Start([]byte)
Stop() error
Recover()
}
注释
1、在编码阶段应该同步写好变量、函数、包的注释,最后可以利用godoc导出文档
。注释必须是完整的句子,句子的结尾应该用句号
作为结尾(英文句号
)。注释推荐用英文
,可以在写代码过程中锻炼英文的阅读和书写能力,而且用英文不会出现各种编码的问题。
2、每个包都应该有一个包注释
,一个位于package子句之前的块注释
或行注释
。包中若有多个go文件,只需要出现在一个go文件中即可。
常量
1、常量名全部由大写字母
组成,并使用下划线分词
:const APP_VER = “1.0”
2、若是枚举类型的常量
,需要先创建相应类型
:
type Scheme string
const (
HTTP Scheme = "http"
HTTPS Scheme = "https"
)
3、如果模块的功能较为复杂、常量名称容易混淆的情况下,为了更好地区分枚举类型
,可以使用完整的前缀
:
type PullRequestStatus int
const (
PULL_REQUEST_STATUS_CONFLICT PullRequestStatus = iota
PULL_REQUEST_STATUS_CHECKING
PULL_REQUEST_STATUS_MERGEABLE
)
变量规则举例
- 变量命名基本上遵循相应的
英文表达
或简写
,在相对简单的环境(对象数量少、针对性强
)中,可以将一些名称由完整单词
简写为单个字母
,例如:
– user 可以简写为 u
– userID 可以简写 uid
– 若变量类型为 bool 类型,则名称应以 Has, Is, Can 或 Allow 开头:
var isExist bool
var hasConflict bool
var canManage bool
var allowGitHook bool
import
- 对import的包进行分组管理,用
换行符分割
,而且标准库作为分组的第一组
。如果你的包引入了三种类型的包:标准库包
,程序内部包
,第三方包
,建议采用如下方式进行组织你的包:在项目中不要使用相对路径
引入包:import "../utils"
import (
"github.com/bitly/go-simplejson"
"strconv"
"container/list"
"gopkg/utils"
)
参数传递
- 对于少量数据,不要传递指针
- 对于大量数据的struct可以考虑使用指针
- 传入参数是map,slice,chan不要传递指针,因为map,slice,chan是
引用类型
,不需要传递指针的指针
单元测试
- 单元测试文件名命名规范为
example_test.go
- 测试用例的函数名称必须以 Test 开头,例如:TestExample
网友评论