Go語言中l(wèi)og模塊用于在程序中輸出日志。
log模塊提供了三類日志輸出接口,Print、Fatal和Panic。Print是普通輸出;Fatal是在執(zhí)行完P(guān)rint后,執(zhí)行 os.Exit(1);Panic是在執(zhí)行完P(guān)rint后調(diào)用panic()方法。log模塊對(duì)每一類接口其提供了3中調(diào)用方式,分別是"Xxxx、 Xxxxln、Xxxxf"。
成都創(chuàng)新互聯(lián) - 成都聯(lián)通服務(wù)器托管,四川服務(wù)器租用,成都服務(wù)器租用,四川網(wǎng)通托管,綿陽服務(wù)器托管,德陽服務(wù)器托管,遂寧服務(wù)器托管,綿陽服務(wù)器托管,四川云主機(jī),成都云主機(jī),西南云主機(jī),成都聯(lián)通服務(wù)器托管,西南服務(wù)器托管,四川/成都大帶寬,機(jī)柜大帶寬租用·托管,四川老牌IDC服務(wù)商
log.Print類接口包括log.Print、log.Println、log.Printf,接口如下:
// Printf calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Printf(format string, v ...interface{}) {
l.Output(2, fmt.Sprintf(format, v...))
}
// Print calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) }
// Println calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) }
log.Print類接口使用示例:
package main
import (
"log"
)
func logPrintTest(){
arr := []int {2,3}
log.Print("Print array ",arr,"\n")
log.Println("Println array",arr)
log.Printf("Printf array with item [%d,%d]\n",arr[0],arr[1])
}
func main() {
logPrintTest()
}
// output
// 2018/10/06 13:38:29 Print array [2 3]
// 2018/10/06 13:38:29 Println array [2 3]
// 2018/10/06 13:38:29 Printf array with item [2,3]
log.Fatal類接口包括log.Fatal、log.Fatalln、log.Fatalf,接口如下:
// Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
func (l *Logger) Fatal(v ...interface{}) {
l.Output(2, fmt.Sprint(v...))
os.Exit(1)
}
// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.Output(2, fmt.Sprintf(format, v...))
os.Exit(1)
}
// Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).
func (l *Logger) Fatalln(v ...interface{}) {
l.Output(2, fmt.Sprintln(v...))
os.Exit(1)
}
?log.Fata接口會(huì)先將日志內(nèi)容打印到標(biāo)準(zhǔn)輸出,接著調(diào)用系統(tǒng)的?os.exit(1)接口,退出程序并返回狀態(tài)1 。但由于直接調(diào)用系統(tǒng)接口退出,defer函數(shù)不會(huì)被調(diào)用。
?log.Fatal接口使用示例:
package main
import (
"log"
"fmt"
)
func logFatalTest(){
level := "Fatal"
defer func() {
fmt.Println("defer Fatal")
}()
log.Fatal("print ",level, " level\n")
// 后續(xù)不會(huì)被執(zhí)行
log.Fatalln("print ",level)
log.Fatalf("print %s level", level)
}
func main() {
logFatalTest()
}
// output
// 2018/10/06 13:47:57 print Fatal level
?log.Fatal接口調(diào)用會(huì)導(dǎo)致程序退出。
log.Panic類接口包括log.Panic、log.Panicln、log.Panicf,接口如下:
// Panic is equivalent to l.Print() followed by a call to panic().
func (l *Logger) Panic(v ...interface{}) {
s := fmt.Sprint(v...)
l.Output(2, s)
panic(s)
}
// Panicf is equivalent to l.Printf() followed by a call to panic().
func (l *Logger) Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
l.Output(2, s)
panic(s)
}
// Panicln is equivalent to l.Println() followed by a call to panic().
func (l *Logger) Panicln(v ...interface{}) {
s := fmt.Sprintln(v...)
l.Output(2, s)
panic(s)
}
log.Panic接口函數(shù)把日志內(nèi)容刷到標(biāo)準(zhǔn)錯(cuò)誤后調(diào)用panic函數(shù)。
log.Panic接口使用示例:
package main
import (
"log"
"fmt"
)
func logPanicTest(){
level := "Panic"
defer func() {
fmt.Println("defer Panic 1")
if err := recover(); err != nil {
fmt.Println(err)
}
}()
log.Panic(level, " level")
defer func() {
fmt.Println("defer Panic 2")
}()
}
func main() {
logPanicTest()
}
// output
// defer Panic 1
// 2018/10/06 13:55:17 Panic level
// Panic level
第一個(gè)defer函數(shù)被調(diào)用并輸出“defer Panic 1”,Panic后聲明的defer不會(huì)執(zhí)行。
Logger是寫入日志的基本組件,log模塊中存在一個(gè)標(biāo)準(zhǔn)Logger,可以直接通過log進(jìn)行訪問,可以直接使用log.xxxx進(jìn)行日志進(jìn)行輸出。但在實(shí)際使用中,不同類型的日志可能擁有需求,僅標(biāo)準(zhǔn)Logger不能滿足日志記錄的需求,通過創(chuàng)建不同的Logger可以將不同類型的日志分類輸出。使用logger前需要首先通過New函數(shù)創(chuàng)建一個(gè)Logger對(duì)象,函數(shù)聲明如下:
func New(out io.Writer, prefix string, flag int) *Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
函數(shù)接收三個(gè)參數(shù)分別是日志輸出的IO對(duì)象,日志前綴和日志包含的通用信息標(biāo)識(shí)位,通過對(duì)參數(shù)進(jìn)行設(shè)置可以對(duì)Logger進(jìn)行定制。其中IO對(duì)象通常是標(biāo)準(zhǔn)輸出os.Stdout,os.Stderr,或者綁定到文件的IO。日志前綴和信息標(biāo)識(shí)位可以對(duì)日志的格式進(jìn)行設(shè)置。
一條日志由三個(gè)部分組成,其結(jié)構(gòu)如下:{日志前綴} {標(biāo)識(shí)1} {標(biāo)識(shí)2} ... {標(biāo)識(shí)n} {日志內(nèi)容}
日志前綴,通過prefix參數(shù)設(shè)置,可以是任意字符串。
標(biāo)識(shí),通過flags參數(shù)設(shè)置,當(dāng)某個(gè)標(biāo)識(shí)被設(shè)置,會(huì)在日志中進(jìn)行顯示,log模塊中定義了如下標(biāo)識(shí),多個(gè)標(biāo)識(shí)通過按位或進(jìn)行組合:
Ldate 顯示當(dāng)前日期(當(dāng)前時(shí)區(qū))
Ltime 顯示當(dāng)前時(shí)間(當(dāng)前時(shí)區(qū))
Lmicroseconds 顯示當(dāng)前時(shí)間(微秒)
Llongfile 包含路徑的完整文件名
Lshortfile 不包含路徑的文件名
LUTC Ldata和Ltime使用UTC時(shí)間
LstdFlags 標(biāo)準(zhǔn)Logger的標(biāo)識(shí),等價(jià)于 Ldate | Ltime
Logger相關(guān)接口如下:
// Flags returns the output flags for the logger.
func (l *Logger) Flags() int {
l.mu.Lock()
defer l.mu.Unlock()
return l.flag
}
// SetFlags sets the output flags for the logger.
func (l *Logger) SetFlags(flag int) {
l.mu.Lock()
defer l.mu.Unlock()
l.flag = flag
}
// Prefix returns the output prefix for the logger.
func (l *Logger) Prefix() string {
l.mu.Lock()
defer l.mu.Unlock()
return l.prefix
}
// SetPrefix sets the output prefix for the logger.
func (l *Logger) SetPrefix(prefix string) {
l.mu.Lock()
defer l.mu.Unlock()
l.prefix = prefix
}
// SetOutput sets the output destination for the standard logger.
func SetOutput(w io.Writer) {
std.mu.Lock()
defer std.mu.Unlock()
std.out = w
}
// Flags returns the output flags for the standard logger.
func Flags() int {
return std.Flags()
}
// SetFlags sets the output flags for the standard logger.
func SetFlags(flag int) {
std.SetFlags(flag)
}
// Prefix returns the output prefix for the standard logger.
func Prefix() string {
return std.Prefix()
}
// SetPrefix sets the output prefix for the standard logger.
func SetPrefix(prefix string) {
std.SetPrefix(prefix)
}
Logger示例如下:
package main
import (
"log"
"os"
)
func main() {
prefix := "[INFO]"
logger := log.New(os.Stdout, prefix, log.LstdFlags | log.Lshortfile)
logger.Print("Hello Go")
logger.SetPrefix("[OUTPUT]")
logger.SetFlags(log.LstdFlags)
logger.Print("Hello Logger")
}
// output
// [INFO]2018/10/06 13:24:44 main.go:11: Hello Go
// [OUTPUT]2018/10/06 13:24:44 Hello Logger
Go的log模塊沒有對(duì)日志進(jìn)行分級(jí)的功能,對(duì)于日志分級(jí)需求可以在log的基礎(chǔ)上進(jìn)行實(shí)現(xiàn)。通過使用log模塊的基礎(chǔ)功能進(jìn)行封裝,可以實(shí)現(xiàn)Log4類似的日志功能。
package logger
import (
"fmt"
"log"
"os"
"os/exec"
"strings"
"time"
)
const (
PanicLevel int = iota
FatalLevel
ErrorLevel
WarnLevel
InfoLevel
DebugLevel
)
type LogFile struct {
level int
logTime int64
fileName string
fileFd *os.File
}
var logFile LogFile
func Config(logFolder string, level int) {
logFile.fileName = logFolder
logFile.level = level
log.SetOutput(logFile)
log.SetFlags(log.Lmicroseconds | log.Lshortfile)
}
func SetLevel(level int) {
logFile.level = level
}
func Debugf(format string, args ...interface{}) {
if logFile.level >= DebugLevel {
log.SetPrefix("debug ")
log.Output(2, fmt.Sprintf(format, args...))
}
}
func Infof(format string, args ...interface{}) {
if logFile.level >= InfoLevel {
log.SetPrefix("info ")
log.Output(2, fmt.Sprintf(format, args...))
}
}
func Warnf(format string, args ...interface{}) {
if logFile.level >= WarnLevel {
log.SetPrefix("warn ")
log.Output(2, fmt.Sprintf(format, args...))
}
}
func Errorf(format string, args ...interface{}) {
if logFile.level >= ErrorLevel {
log.SetPrefix("error ")
log.Output(2, fmt.Sprintf(format, args...))
}
}
func Fatalf(format string, args ...interface{}) {
if logFile.level >= FatalLevel {
log.SetPrefix("fatal ")
log.Output(2, fmt.Sprintf(format, args...))
}
}
func (me LogFile) Write(buf []byte) (n int, err error) {
if me.fileName == "" {
fmt.Printf("consol: %s", buf)
return len(buf), nil
}
if logFile.logTime+3600 < time.Now().Unix() {
logFile.createLogFile()
logFile.logTime = time.Now().Unix()
}
if logFile.fileFd == nil {
return len(buf), nil
}
return logFile.fileFd.Write(buf)
}
func (me *LogFile) createLogFile() {
logdir := "./"
if index := strings.LastIndex(me.fileName, "/"); index != -1 {
logdir = me.fileName[0:index] + "/"
os.MkdirAll(me.fileName[0:index], os.ModePerm)
}
now := time.Now()
filename := fmt.Sprintf("%s_%04d%02d%02d_%02d%02d", me.fileName, now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute())
if err := os.Rename(me.fileName, filename); err == nil {
go func() {
tarCmd := exec.Command("tar", "-zcf", filename+".tar.gz", filename, "--remove-files")
tarCmd.Run()
rmCmd := exec.Command("/bin/sh", "-c", "find "+logdir+` -type f -mtime +2 -exec rm {} \;`)
rmCmd.Run()
}()
}
for index := 0; index < 10; index++ {
if fd, err := os.OpenFile(me.fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModeExclusive); nil == err {
me.fileFd.Sync()
me.fileFd.Close()
me.fileFd = fd
break
}
me.fileFd = nil
}
}
上述logger模塊封裝的功能如下:
A、支持歸檔輸出,一個(gè)小時(shí)壓縮歸檔一份
B、最多保留三天的日志
C、支持日志級(jí)別自定義
D、如果沒有指定輸出文件默認(rèn)輸出到控制臺(tái)。
E、支持輸出文件名行號(hào),以及時(shí)間、日志界別?
Go語言通過regexp標(biāo)準(zhǔn)包為正則表達(dá)式提供了官方支持。在Go語言環(huán)境中可以使用下列命令查看正則表達(dá)式的語法:go doc regexp/syntax
Regexp是一個(gè)編譯好的正則表達(dá)式對(duì)象。
type Regexp struct {
// read-only after Compile
regexpRO
// cache of machines for running regexp
mu sync.Mutex
machine []*machine
}
通常需要使用正則表達(dá)式構(gòu)建一個(gè)正則對(duì)象
func Match(pattern string, b []byte) (matched bool, err error)
func MatchString(pattern string, s string) (matched bool, err error)
func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)
判斷在b中能否找到pattern所匹配的字符串func Compile(expr string) (*Regexp, error)
將正則表達(dá)式編譯成一個(gè)正則對(duì)象(使用PERL語法)。
該正則對(duì)象會(huì)采用“l(fā)eftmost-first”模式。選擇第一個(gè)匹配結(jié)果。
如果正則表達(dá)式語法錯(cuò)誤,則返回錯(cuò)誤信息。func CompilePOSIX(expr string) (*Regexp, error)
將正則表達(dá)式編譯成一個(gè)正則對(duì)象(正則語法限制在 POSIX ERE 范圍內(nèi))。
該正則對(duì)象會(huì)采用“l(fā)eftmost-longest”模式。選擇最長(zhǎng)的匹配結(jié)果。
POSIX 語法不支持Perl的語法格式:\d、\D、\s、\S、\w、\W
如果正則表達(dá)式語法錯(cuò)誤,則返回錯(cuò)誤信息。
func MustCompile(str string) *Regexp
func MustCompilePOSIX(str string) *Regexp
將正則表達(dá)式編譯成一個(gè)正則對(duì)象,但會(huì)在解析失敗時(shí)panicfunc (re *Regexp) Longest()
讓正則表達(dá)式在之后的搜索中都采用“l(fā)eftmost-longest”模式。func (re *Regexp) String() string
返回編譯時(shí)使用的正則表達(dá)式字符串func (re *Regexp) NumSubexp() int
返回正則表達(dá)式中分組的數(shù)量func (re *Regexp) SubexpNames() []string
返回正則表達(dá)式中分組的名字
第 0 個(gè)元素表示整個(gè)正則表達(dá)式的名字,永遠(yuǎn)是空字符串。func (re *Regexp) LiteralPrefix() (prefix string, complete bool)
返回正則表達(dá)式必須匹配到的字面前綴(不包含可變部分)。
如果整個(gè)正則表達(dá)式都是字面值,則 complete 返回 true。
package main
import (
"regexp"
"fmt"
)
var mailRegexp = regexp.MustCompile(`([A-Za-z0-9]+)@([A-Za-z0-9.]+)\.([A-Za-z0-9.]+)`)
func main() {
s := " hello's email is hellogo@gmail.com"
matches := mailRegexp.FindStringSubmatch(s)
fmt.Println(matches)// [hellogo@gmail.com hellogo gmail com]
fmt.Println(matches[0]) // hellogo@gmail.com
fmt.Println(matches[1]) // hellogo
fmt.Println(matches[2]) // gmail
fmt.Println(matches[3]) // com
}
strconv提供了字符串與基本類型的轉(zhuǎn)換函數(shù)接口。
func ParseBool(str string) (value bool, err error)
ParseBool將字符串轉(zhuǎn)換為布爾值。接受真值:1, t, T, TRUE, true, True;接受假值:0, f, F, FALSE, false, False;其它任何值都返回一個(gè)錯(cuò)誤。
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.ParseBool("1")) // true
fmt.Println(strconv.ParseBool("t")) // true
fmt.Println(strconv.ParseBool("T")) // true
fmt.Println(strconv.ParseBool("true")) // true
fmt.Println(strconv.ParseBool("True")) // true
fmt.Println(strconv.ParseBool("TRUE")) // true
fmt.Println(strconv.ParseBool("TRue"))
// false strconv.ParseBool: parsing "TRue": invalid syntax
fmt.Println(strconv.ParseBool("0")) // false
fmt.Println(strconv.ParseBool("f")) // false
fmt.Println(strconv.ParseBool("F")) // false
fmt.Println(strconv.ParseBool("false")) // false
fmt.Println(strconv.ParseBool("False")) // false
fmt.Println(strconv.ParseBool("FALSE")) // false
fmt.Println(strconv.ParseBool("FALse"))
// false strconv.ParseBool: parsing "FAlse": invalid syntax
}
func FormatBool(b bool) string
FormatBool將布爾值轉(zhuǎn)換為字符串"true"或"false"
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.FormatBool(0 < 1)) // true
fmt.Println(strconv.FormatBool(0 > 1)) // false
}
func AppendBool(dst []byte, b bool) []byte
AppendBool將布爾值b轉(zhuǎn)換為字符串"true"或"false",然后將結(jié)果追加到dst的尾部,返回追加后的[]byte。
package main
import (
"fmt"
"strconv"
)
func main() {
rst := make([]byte, 0)
rst = strconv.AppendBool(rst, 0 < 1)
fmt.Printf("%s\n", rst) // true
rst = strconv.AppendBool(rst, 0 > 1)
fmt.Printf("%s\n", rst) // truefalse
}
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt將字符串轉(zhuǎn)換為int類型
s:要轉(zhuǎn)換的字符串
base:進(jìn)位制(2進(jìn)制到36進(jìn)制)
bitSize:指定整數(shù)類型(0:int、8:int8、16:int16、32:int32、64:int64)
返回轉(zhuǎn)換后的結(jié)果和轉(zhuǎn)換時(shí)遇到的錯(cuò)誤,如果base為0,則根據(jù)字符串的前綴判斷進(jìn)位制(0x:16,0:8,其它:10)。
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.ParseInt("123", 10, 8))
// 123
fmt.Println(strconv.ParseInt("12345", 10, 8))
// 127 strconv.ParseInt: parsing "12345": value out of range
fmt.Println(strconv.ParseInt("2147483647", 10, 0))
// 2147483647
fmt.Println(strconv.ParseInt("0xFF", 16, 0))
// 0 strconv.ParseInt: parsing "0xFF": invalid syntax
fmt.Println(strconv.ParseInt("FF", 16, 0))
// 255
fmt.Println(strconv.ParseInt("0xFF", 0, 0))
// 255
}
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
ParseUint將字符串轉(zhuǎn)換為uint類型
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.ParseUint("FF", 16, 8))
// 255
}
func Atoi(s string) (i int, err error)
Atoi相當(dāng)于ParseInt(s, 10, 0)
func FormatInt(i int64, base int) string
FormatUint將int型整數(shù)i轉(zhuǎn)換為字符串形式
base:進(jìn)位制(2進(jìn)制到36進(jìn)制),大于10進(jìn)制的數(shù),返回值使用小寫字母'a'到'z'
package main
import (
"fmt"
"strconv"
)
func main() {
i := int64(-2048)
fmt.Println(strconv.FormatInt(i, 2)) // -100000000000
fmt.Println(strconv.FormatInt(i, 8)) // -4000
fmt.Println(strconv.FormatInt(i, 10)) // -2048
fmt.Println(strconv.FormatInt(i, 16)) // -800
fmt.Println(strconv.FormatInt(i, 36)) // -1kw
}
func Itoa(i int) string
Itoa相當(dāng)于FormatInt(i, 10)
func AppendInt(dst []byte, i int64, base int) []byte
AppendInt將int型整數(shù)i轉(zhuǎn)換為字符串形式,并追加到dst的尾部
i:要轉(zhuǎn)換的字符串,base:進(jìn)位制,返回追加后的[]byte。
func AppendUint(dst []byte, i uint64, base int) []byte
AppendUint將uint型整數(shù)i轉(zhuǎn)換為字符串形式,并追加到dst的尾部
i:要轉(zhuǎn)換的字符串,base:進(jìn)位制,返回追加后的[]byte。
func ParseFloat(s string, bitSize int) (f float64, err error)
ParseFloat將字符串轉(zhuǎn)換為浮點(diǎn)數(shù),
s:要轉(zhuǎn)換的字符串
bitSize:指定浮點(diǎn)類型(32:float32、64:float64)
如果s是合法的格式,而且接近一個(gè)浮點(diǎn)值,則返回浮點(diǎn)數(shù)的四舍五入值(依據(jù) IEEE754 的四舍五入標(biāo)準(zhǔn));如果s不是合法的格式,則返回“語法錯(cuò)誤”;如果轉(zhuǎn)換結(jié)果超出bitSize范圍,則返回“超出范圍”。
package main
import (
"fmt"
"strconv"
)
func main() {
s := "0.12345678901234567890"
f, err := strconv.ParseFloat(s, 32)
fmt.Println(f, err) // 0.12345679104328156
fmt.Println(float32(f), err) // 0.12345679
f, err = strconv.ParseFloat(s, 64)
fmt.Println(f, err) // 0.12345678901234568
}
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
FormatFloat 將浮點(diǎn)數(shù) f 轉(zhuǎn)換為字符串值
f:要轉(zhuǎn)換的浮點(diǎn)數(shù)
fmt:格式標(biāo)記(b、e、E、f、g、G)
prec:精度(數(shù)字部分的長(zhǎng)度,不包括指數(shù)部分)
bitSize:指定浮點(diǎn)類型(32:float32、64:float64)
格式標(biāo)記:
'b' (-ddddp±ddd,二進(jìn)制指數(shù))
'e' (-d.dddde±dd,十進(jìn)制指數(shù))
'E' (-d.ddddE±dd,十進(jìn)制指數(shù))
'f' (-ddd.dddd,沒有指數(shù))
'g' ('e':大指數(shù),'f':其它情況)
'G' ('E':大指數(shù),'f':其它情況)
如果格式標(biāo)記為 'e','E'和'f',則prec表示小數(shù)點(diǎn)后的數(shù)字位數(shù)
如果格式標(biāo)記為 'g','G',則prec表示總的數(shù)字位數(shù)(整數(shù)部分+小數(shù)部分)
package main
import (
"fmt"
"strconv"
)
func main() {
f := 100.12345678901234567890123456789
fmt.Println(strconv.FormatFloat(f, 'b', 5, 32))
// 13123382p-17
fmt.Println(strconv.FormatFloat(f, 'e', 5, 32))
// 1.00123e+02
fmt.Println(strconv.FormatFloat(f, 'E', 5, 32))
// 1.00123E+02
fmt.Println(strconv.FormatFloat(f, 'f', 5, 32))
// 100.12346
fmt.Println(strconv.FormatFloat(f, 'g', 5, 32))
// 100.12
fmt.Println(strconv.FormatFloat(f, 'G', 5, 32))
// 100.12
fmt.Println(strconv.FormatFloat(f, 'b', 30, 32))
// 13123382p-17
fmt.Println(strconv.FormatFloat(f, 'e', 30, 32))
// 1.001234588623046875000000000000e+02
fmt.Println(strconv.FormatFloat(f, 'E', 30, 32))
// 1.001234588623046875000000000000E+02
fmt.Println(strconv.FormatFloat(f, 'f', 30, 32))
// 100.123458862304687500000000000000
fmt.Println(strconv.FormatFloat(f, 'g', 30, 32))
// 100.1234588623046875
fmt.Println(strconv.FormatFloat(f, 'G', 30, 32))
// 100.1234588623046875
}
func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte
AppendFloat將浮點(diǎn)數(shù)f轉(zhuǎn)換為字符串值,并將轉(zhuǎn)換結(jié)果追加到dst的尾部,返回追加后的[]byte
package main
import (
"fmt"
"strconv"
)
func main() {
f := 100.12345678901234567890123456789
b := make([]byte, 0)
b = strconv.AppendFloat(b, f, 'f', 5, 32)
b = append(b, " "...)
b = strconv.AppendFloat(b, f, 'e', 5, 32)
fmt.Printf("%s", b) // 100.12346 1.00123e+0
}
func Quote(s string) string
Quote將字符串s轉(zhuǎn)換為“雙引號(hào)”引起來的字符串
其中的特殊字符將被轉(zhuǎn)換為“轉(zhuǎn)義字符”,“不可顯示的字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.Quote(`/home/user`)) // "/home/user"
}
func AppendQuote(dst []byte, s string) []byte
AppendQuote將字符串s轉(zhuǎn)換為“雙引號(hào)”引起來的字符串,并將結(jié)果追加到dst的尾部,返回追加后的[]byte。其中的特殊字符將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func QuoteToASCII(s string) string
QuoteToASCII將字符串s轉(zhuǎn)換為“雙引號(hào)”引起來的ASCII字符串,“非ASCII字符”和“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func AppendQuoteToASCII(dst []byte, s string) []byte
AppendQuoteToASCII將字符串s轉(zhuǎn)換為“雙引號(hào)”引起來的 ASCII 字符串,并將結(jié)果追加到dst的尾部,返回追加后的[]byte,“非 ASCII 字符”和“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func QuoteRune(r rune) string
QuoteRune將Unicode字符轉(zhuǎn)換為“單引號(hào)”引起來的字符串,“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func AppendQuoteRune(dst []byte, r rune) []byte
AppendQuoteRune將Unicode字符轉(zhuǎn)換為“單引號(hào)”引起來的字符串,并將結(jié)果追加到dst的尾部,返回追加后的[]byte。“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func QuoteRuneToASCII(r rune) string
QuoteRuneToASCII將Unicode字符轉(zhuǎn)換為“單引號(hào)”引起來的ASCII字符串,“非 ASCII字符”和“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte
AppendQuoteRune將Unicode字符轉(zhuǎn)換為“單引號(hào)”引起來的ASCII字符串,并將結(jié)果追加到dst的尾部,返回追加后的[]byte,“非 ASCII 字符”和“特殊字符”將被轉(zhuǎn)換為“轉(zhuǎn)義字符”。
func CanBackquote(s string) bool
CanBackquote判斷字符串s是否可以表示為一個(gè)單行的“反引號(hào)”字符串,字符串中不能含有控制字符(除了\t)和“反引號(hào)”字符,否則返回false。
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
UnquoteChar 將 s 中的第一個(gè)字符“取消轉(zhuǎn)義”并解碼
s:轉(zhuǎn)義后的字符串
quote:字符串使用的“引號(hào)符”(用于對(duì)引號(hào)符“取消轉(zhuǎn)義”)
value: 解碼后的字符
multibyte:value是否為多字節(jié)字符
tail: 字符串s除去value后的剩余部分
error:返回s中是否存在語法錯(cuò)誤
參數(shù) quote 為“引號(hào)符”
如果設(shè)置為單引號(hào),則 s 中允許出現(xiàn) \' 字符,不允許出現(xiàn)單獨(dú)的 ' 字符
如果設(shè)置為雙引號(hào),則 s 中允許出現(xiàn) \" 字符,不允許出現(xiàn)單獨(dú)的 " 字符
如果設(shè)置為 0,則不允許出現(xiàn) \' 或 \" 字符,可以出現(xiàn)單獨(dú)的 ' 或 " 字符
func Unquote(s string) (t string, err error)
Unquote 將“帶引號(hào)的字符串” s 轉(zhuǎn)換為常規(guī)的字符串(不帶引號(hào)和轉(zhuǎn)義字符)
s可以是“單引號(hào)”、“雙引號(hào)”或“反引號(hào)”引起來的字符串(包括引號(hào)本身)
如果s是單引號(hào)引起來的字符串,則返回該該字符串代表的字符
func IsPrint(r rune) bool
IsPrint判斷Unicode字符r是否是一個(gè)可顯示的字符,空格可以顯示,而\t則不能顯示。
time包提供顯示和計(jì)算時(shí)間用的函數(shù)。Go中時(shí)間處理依賴的數(shù)據(jù)類型:?time.Time,?time.Month,?time.Weekday,?time.Duration,?time.Location。
time.Time?代表一個(gè)納秒精度的時(shí)間點(diǎn),定義如下:
type Time struct {
sec int64 // 從1年1月1日 00:00:00 UTC 至今過去的秒數(shù)
nsec int32 // 最近一秒到下一秒過去的納秒數(shù)
loc *Location // 時(shí)區(qū)
}
time.Time使用示例:
package main
import (
"fmt"
"time"
)
func main() {
var t time.Time // 定義 time.Time 類型變量
t = time.Now() // 獲取當(dāng)前時(shí)間
fmt.Printf("時(shí)間: %v, 時(shí)區(qū): %v, 時(shí)間類型: %T\n", t, t.Location(), t)
// time.UTC() time 返回UTC 時(shí)區(qū)的時(shí)間
fmt.Printf("時(shí)間: %v, 時(shí)區(qū): %v, 時(shí)間類型: %T\n", t.UTC(), t.UTC().Location(), t)
}
// output
// 時(shí)間: 2018-10-06 15:31:06.730640277 +0800 CST m=+0.000273307, 時(shí)區(qū): Local, 時(shí)間類型: time.Time
// 時(shí)間: 2018-10-06 07:31:06.730640277 +0000 UTC, 時(shí)區(qū): UTC, 時(shí)間類型: time.Time
時(shí)間獲取的接口:
func Now() Time {} // 當(dāng)前本地時(shí)間
func Unix(sec int64, nsec int64) Time {} // 根據(jù)時(shí)間戳返回本地時(shí)間
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {} // 返回指定時(shí)間
時(shí)間顯示的接口:
func (t Time) UTC() Time {} // 獲取指定時(shí)間在UTC 時(shí)區(qū)的時(shí)間表示
func (t Time) Local() Time {} // 以本地時(shí)區(qū)表示
func (t Time) In(loc *Location) Time {} // 時(shí)間在指定時(shí)區(qū)的表示
func (t Time) Format(layout string) string {} // 按指定格式顯示時(shí)間
日期信息獲取的接口:
func (t Time) Date() (year int, month Month, day int) {} // 返回時(shí)間的日期信息
func (t Time) Year() int {} // 返回年
func (t Time) Month() Month {} // 月
func (t Time) Day() int {} // 日
func (t Time) Weekday() Weekday {} // 星期
func (t Time) ISOWeek() (year, week int) {} // 返回年,星期范圍編號(hào)
func (t Time) Clock() (hour, min, sec int) {} // 返回時(shí)間的時(shí)分秒
func (t Time) Hour() int {} // 返回小時(shí)
func (t Time) Minute() int {} // 分鐘
func (t Time) Second() int {} // 秒
func (t Time) Nanosecond() int {} // 納秒
func (t Time) YearDay() int {} // 一年中對(duì)應(yīng)的天
func (t Time) Location() *Location {} // 時(shí)間的時(shí)區(qū)
func (t Time) Zone() (name string, offset int) {} // 時(shí)間所在時(shí)區(qū)的規(guī)范名和想對(duì)UTC 時(shí)間偏移量
func (t Time) Unix() int64 {} // 時(shí)間轉(zhuǎn)為時(shí)間戳
func (t Time) UnixNano() int64 {} // 時(shí)間轉(zhuǎn)為時(shí)間戳(納秒)
時(shí)間比較與計(jì)算的接口:
func (t Time) IsZero() bool {} // 是否是零時(shí)時(shí)間
func (t Time) After(u Time) bool {} // 時(shí)間在u 之前
func (t Time) Before(u Time) bool {} // 時(shí)間在u 之后
func (t Time) Equal(u Time) bool {} // 時(shí)間與u 相同
func (t Time) Add(d Duration) Time {} // 返回t +d 的時(shí)間點(diǎn)
func (t Time) Sub(u Time) Duration {} // 返回 t-u
func (t Time) AddDate(years int, months int, days int) Time {} //返回增加了給出的年份、月份和天數(shù)的時(shí)間點(diǎn)Time
時(shí)間序列化的接口:
func (t Time) MarshalBinary() ([]byte, error) {} // 時(shí)間序列化
func (t Time) UnmarshalBinary(data []byte) error {} // 反序列化
func (t Time) MarshalJSON() ([]byte, error) {} // 時(shí)間序列化
func (t Time) MarshalText() ([]byte, error) {} // 時(shí)間序列化
func (t Time) GobEncode() ([]byte, error) {} // 時(shí)間序列化
func (t Time) GobDecode() ([]byte, error) {} // 時(shí)間序列化
time.Month?代表一年中的某個(gè)月
type Month int
const (
January Month = 1 + iota
February
March
April
May
June
July
August
September
October
November
December
)
time.Weekday?代表一周的周幾
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
time.Duration?類型代表兩個(gè)時(shí)間點(diǎn)之間經(jīng)過的納秒數(shù),可表示的最長(zhǎng)時(shí)間段約為290年。
type Duration int64
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
輸出和改變時(shí)間段單位的接口:
func (d Duration) String() string // 格式化輸出 Duration
func (d Duration) Nanoseconds() int64 // 將時(shí)間段表示為納秒
func (d Duration) Seconds() float64 // 將時(shí)間段表示為秒
func (d Duration) Minutes() float64 // 將時(shí)間段表示為分鐘
func (d Duration) Hours() float64 // 將時(shí)間段表示為小時(shí)
Location代表一個(gè)地點(diǎn),以及該地點(diǎn)所在的時(shí)區(qū)信息。北京時(shí)間可以使用?Asia/Shanghai。
type Location struct {
name string
zone []zone
tx []zoneTrans
cacheStart int64
cacheEnd int64
cacheZone *zone
}
var UTC *Location = &utcLoc
var Local *Location = &localLoc
時(shí)區(qū)導(dǎo)出的接口:
func (l *Location) String() string // 輸出時(shí)區(qū)名
func FixedZone(name string, offset int) *Location // FixedZone 使用給定的地點(diǎn)名name和時(shí)間偏移量offset(單位秒)創(chuàng)建并返回一個(gè)Location
func LoadLocation(name string) (*Location, error) // LoadLocation 使用給定的名字創(chuàng)建Location
func Sleep(d Duration)?
阻塞當(dāng)前go協(xié)程至少d代表的時(shí)間段。d<=0時(shí),Sleep會(huì)立刻返回。
Go語言使用error類型來返回函數(shù)執(zhí)行過程中遇到的錯(cuò)誤,如果返回error值為nil,則表示未遇到錯(cuò)誤,否則error會(huì)返回一個(gè)字符串。error是一個(gè)預(yù)定義標(biāo)識(shí)符,代表一個(gè)Go語言內(nèi)建的接口類型,任何自定義的錯(cuò)誤類型都要實(shí)現(xiàn)Error接口函數(shù)。
type error interface {
Error() string
}
func New(text string) error
將字符串text包裝成一個(gè)error對(duì)象返回?
import (
"errors"
"fmt"
)
var ErrUnexpectedEOF = errors.New("unexpected EOF")
func main() {
fmt.Println(ErrUnexpectedEOF)
}
Go語言工程開發(fā)中,通常需要根據(jù)使用場(chǎng)景定制不同的error類型,此時(shí)需要實(shí)現(xiàn)Error接口。
package errors_test
import (
"fmt"
"time"
)
// MyError is an error implementation that includes a time and message.
type MyError struct {
When time.Time
What string
}
func (e MyError) Error() string {
return fmt.Sprintf("%v: %v", e.When, e.What)
}
func oops() error {
return MyError{
time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC),
"the file system has gone away",
}
}
func Example() {
if err := oops(); err != nil {
fmt.Println(err)
}
// Output: 1989-03-15 22:30:00 +0000 UTC: the file system has gone away
}
名稱欄目:Go語言開發(fā)(十一)、Go語言常用標(biāo)準(zhǔn)庫一
本文路徑:http://muchs.cn/article14/ippsge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、網(wǎng)站改版、建站公司、域名注冊(cè)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)