社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
func main() {
// fmt.Fprintf 向文件中写内容
fileObj, err := os.OpenFile("./a.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal(err)
}
defer fileObj.Close()
s := "text"
fmt.Fprintf(fileObj, "%s\n", s)
// 格式化字符串
o := struct{ name string }{"zzdd"}
fmt.Printf("%v\n", o) // 值的默认格式
fmt.Printf("%+v\n", o) // 同时输出字段名
fmt.Printf("%#v\n", o) // 值的go语法
fmt.Printf("%T\n", o) // 值的类型
fmt.Printf("100%%\n") // 打印百分号
// 获取标准输入,输入字段以空格分割
// var (
// name string
// age int
// )
// fmt.Print("please input your name and age: ")
// fmt.Scan(&name, &age) // 注意这里的符号 &
// fmt.Printf("name: %s age: %d\n", name, age)
// 获取标准输入,若用户输入包含空格,使用bufio实现
reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
fmt.Print("请输入: ")
text, _ := reader.ReadString('\n') // 读到换行
text = strings.TrimSpace(text)
fmt.Printf("%#v\n", text)
}
/*
==========
{zzdd}
{name:zzdd}
struct { name string }{name:"zzdd"}
struct { name string }
100%
请输入: qq is good
"qq is good"
*/
// 一个好的实践是将这部分通用配置放到init函数中
func init() {
logFile, err := os.OpenFile("./a.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
return
}
// 将日志写入文件
log.SetOutput(logFile)
// 控制输出日志信息的细节
log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
// 配置日志信息前缀
log.SetPrefix("[prefix_name] ")
}
func main() {
// log.New 可以自定义日志输出
// func New(out io.Writer, prefix string, flag int) *Logger
logger := log.New(os.Stdout, "[prefix New] ", log.Lshortfile|log.Ldate|log.Ltime)
logger.Println("logger log")
log.Println("i am log")
v := "this is log"
log.Printf("%s", v)
// log.Fatalln("fatal") // Fatalln会在写入日志后调用os.Exit(1)
/*
[prefix New] 2021/03/16 09:57:35 main.go:27: logger log
cat a.log
[prefix_name] 2021/03/16 10:00:25.470469 main.go:28: i am log
[prefix_name] 2021/03/16 10:00:25.470494 main.go:30: this is log
*/
}
时间类型输出
unix时间戳
定时器
格式化时间(Go的诞生时间2006年1月2号15点04分)
package main
import (
"fmt"
"time"
)
func main() {
// 时间类型
now := time.Now() // 当前时间
year := now.Year() // 当前年
month := now.Month() // 当前月
day := now.Day()
fmt.Println(now)
fmt.Printf("%d-%d-%d\n", year, month, day)
timestamp := now.Unix() // 当前unix时间戳
fmt.Printf("%v\n", timestamp)
// 时间戳
timeObj := time.Unix(timestamp, 0) // 将unix时间戳转换为时间
fmt.Println(timeObj)
hour := timeObj.Hour() //时
minute := timeObj.Minute() //分
second := timeObj.Second() //秒
fmt.Printf("%d:%d:%d\n", hour, minute, second)
// 定时器
// ticker := time.Tick(time.Second) // 间隔1秒
// for i := range ticker {
// fmt.Println(i)
// }
// 格式化时间,按照Go的诞生时间2006年1月2号15点04分
// 24小时制
fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
// 12小时制
fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
}
/*
========================
2021-03-15 18:18:32.977383 +0800 CST m=+0.000065185
2021-3-15
1615803512
2021-03-15 18:18:32 +0800 CST
18:18:32
2021-03-15 18:18:32.977 Mon Mar
2021-03-15 06:18:32.977 PM Mon Mar
*/
strconv实现了基本数据类型和其字符串表示的相互转换。
func main() {
// int类型转化为string类型
var i int = 4
var itostr string = strconv.Itoa(i)
fmt.Println(reflect.TypeOf(itostr), itostr)
// str类型转化为int类型
var str string = "5"
strtoi, err := strconv.Atoi(str)
if err != nil {
fmt.Println("convert failed")
}
fmt.Println(reflect.TypeOf(strtoi), strtoi)
// Parse函数用于转换字符串为给定类型的值
b1, err := strconv.ParseBool("true")
f1, err := strconv.ParseFloat("3.141", 64)
i1, err := strconv.ParseInt("-2", 10, 64)
u1, err := strconv.ParseUint("2", 10, 64)
fmt.Println(reflect.TypeOf(b1), b1)
fmt.Println(reflect.TypeOf(f1), f1)
fmt.Println(reflect.TypeOf(i1), i1)
fmt.Println(reflect.TypeOf(u1), u1)
//Format函数实现了将给定类型数据格式化为string类型数据的功能
s1 := strconv.FormatBool(true)
s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
s3 := strconv.FormatInt(-2, 16)
s4 := strconv.FormatUint(2, 16)
fmt.Println(reflect.TypeOf(s1), s1)
fmt.Println(reflect.TypeOf(s2), s2)
fmt.Println(reflect.TypeOf(s3), s3)
fmt.Println(reflect.TypeOf(s4), s4)
}
/*
string 4
int 5
bool
string true
bool true
float64 3.141
int64 -2
uint64 2
string true
string 3.1415E+00
string -2
string 2
*/
}
约定1:与测试的代码在同级目录,并以 “文件名_test.go” 命名
约定2:测试函数以Test开头
约定3:got want模式,有助于快速发现失败的原因
a.go
func Greeting(s string) string {
return ("hello " + s)
}
a_test.go
func TestGreeting(t *testing.T) { // TestGreeting因为是Test开头,表明是一个测试,类型T包含很多用于测试代码的函数
got := Greeting("zzd") // got表示要测试的值
want := "hello zzd" // want表示期望的值
if got != want {
t.Fatalf("expected %v, got %v", want, got) // 错误友情提示
}
}
/*
终端执行
go test,显示测试结果,若将want内容修改为其它,则会打印错误友情提示
PASS
ok 06 0.017s
*/
go test -cover
PASS
coverage: 33.3% of statements
ok 06 0.017s
// 定义转化函数,匹配输入
func translate(s string) string {
switch s {
case "zh-gz":
return "hello "
case "zh-bj":
return "hi "
case "zh-sh":
return "good "
default:
return "hello "
}
}
// 定义got拼接
func Greeting(name, locale string) string {
salutation := translate(locale)
return (salutation + name)
}
// 使用表格驱动测试,能够同时测试很多条件
type GreetingTest struct {
name string
locale string
want string
}
// 表格数据赋值
var greetingTests = []GreetingTest{
{"aaa", "zh-gz", "hello aaa"},
{"ddd", "zh-bj", "hi ddd"},
{"ccc", "zh-sh", "good ccc"},
}
func TestGreeting(t *testing.T) { // TestGreeting因为是Test开头,表明是一个测试,类型T包含很多用于测试代码的函数
for _, test := range greetingTests {
got := Greeting(test.name, test.locale)
if got != test.want {
t.Errorf("Greeting(%s,%s)=%v;want %v", test.name, test.locale, got, test.want)
}
}
}
/*
go test
PASS
ok 06 0.017s
*/
package temp
import (
"bytes"
"strings"
"testing"
)
// 字符串拼接几种方法性能(基准)测试,
// 1、直接赋值
func StringAssign(j int) string {
var s string
for i := 0; i < j; i++ {
s += "a"
}
return s
}
// 2、使用join赋值
func StringAppend(j int) string {
s := []string{}
for i := 0; i < j; i++ {
s = append(s, "a")
}
return strings.Join(s, "")
}
// 3、使用缓冲区赋值
func StringBuffer(j int) string {
var buffer bytes.Buffer
for i := 0; i < j; i++ {
buffer.WriteString("a")
}
return buffer.String()
}
// 性能(基准)测试需要以Benchmark打头,接受一个类型为B的参数,并对函数进行基准测试
func BenchmarkStringAssign(b *testing.B) {
for i := 0; i < b.N; i++ {
StringAssign(100)
}
}
func BenchmarkStringAppend(b *testing.B) {
for i := 0; i < b.N; i++ {
StringAppend(100)
}
}
func BenchmarkStringBuffer(b *testing.B) {
for i := 0; i < b.N; i++ {
StringBuffer(100)
}
}
/*
//终端执行,结论:缓冲区速度最快
go test -bench=.
BenchmarkStringAssign-12 284379 3896 ns/op
BenchmarkStringAppend-12 558100 1974 ns/op
BenchmarkStringBuffer-12 1902393 632 ns/op
PASS
ok 06 4.138s
*/
// 将日志写入文件
f, err := os.OpenFile("stdout.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close() // defer延时关闭文件
log.SetOutput(f) // 通过SetOutput可以将标准输出直接输出到文件
var count = 5
for i := 0; i < count; i++ {
log.Printf("log iteration %d", i)
}
ioutil包用于执行一些常见的文件处理操作,底层使用os包,复杂操作可以用os包
/*
*/
type Config struct {
Name string `json:name`
Age float64 `json:age`
God bool `json:god`
}
func main() {
// 读取文件
fileBytes, err := ioutil.ReadFile("stdout.log") // 返回一个字节切片
if err != nil {
log.Fatal(err)
}
fileString := string(fileBytes) // 将字节切片转换为字符串
fmt.Println(fileString)
// 创建文件
b := make([]byte, 0) // WriteFile需接受字节切片,创建一个,并给文件赋权
err1 := ioutil.WriteFile("err.log", b, 0644)
if err1 != nil {
log.Fatal(err1)
}
// 将文本写入文件,文件不存在则创建
s := "hello world"
err2 := ioutil.WriteFile("err1.log", []byte(s), 0644)
if err != nil {
log.Fatal(err2)
}
// 列出当前目录内容,ReadDir返回列表,包含Name、Size等
files, err3 := ioutil.ReadDir(".")
if err3 != nil {
log.Fatal(err3)
}
for _, file := range files {
fmt.Println(file.Name(), file.Size(), file.IsDir(), file.Mode(), file.ModTime())
}
// 复制文件,使用os
from, err := os.Open("err1.log") // 读取文件
if err != nil {
log.Fatal(err)
}
defer from.Close() // 一定不要忘记关闭文件
to, err := os.OpenFile("err1.copy", os.O_RDWR|os.O_CREATE, 0666) // 打开文件
if err != nil {
log.Fatal(err)
}
defer to.Close() // 一定不要忘记关闭文件
_, err = io.Copy(to, from) // io.Copy(目标,来源)
if err != nil {
log.Fatal(err)
}
// 删除文件,需要先判断是否存在
// err5 := os.Remove("./err.log")
// if err5 != nil {
// log.Fatal(err5)
// }
// 从json文件中读取配置
f, err := ioutil.ReadFile("config.json")
if err != nil {
log.Fatal(err)
}
c := Config{}
err = json.Unmarshal(f, &c) // json解码
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", c.Name)
}
func main() {
// 1.获取命令行参数os.Args
// for i, arg := range os.Args {
// fmt.Println("arg:", i, arg)
// }
// 2.获取命令行参数使用flag包
// flag.Usage自定义帮助文本
flag.Usage = func() {
usageText := `Usage cli [OPTION]
An example of customizing usage output
-s, --s string help text
-i, --i int help text
-b, --b bool help text
`
fmt.Fprintln(os.Stderr, usageText)
}
// flag.String表示接收string类型参数
s := flag.String("s", "hi", "string help text")
i := flag.Int("i", 1, "int help text")
b := flag.Bool("b", false, "bool help text")
//flag.Parse 传递声明的参数
flag.Parse()
fmt.Println("value of s:", *s)
fmt.Println("value of i:", *i)
fmt.Println("value of b:", *b)
}
func flagUsage() {
usageText := `script is a string handle cli tool.
Usage:
./script command [arguments]
The commands are:
upper
lower
Use "./script [command] --help" for more information about a command.
`
fmt.Fprintf(os.Stderr, "%s\n", usageText)
}
func main() {
// flag.Usage自定义帮助文本
flag.Usage = flagUsage
// 添加子命
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!