fmt
文档 fmt
使用 fmt
输出一些东西,如果你想要自定义一些输出,fmt
提供了四种实现方式:
go
type Formatter interface {
Format(f State, verb rune)
}
type Stringer interface {
String() string
}
type GoStringer interface {
GoString() string
}
type error interface {
Error() string
}
只要某个结构体实现了这些方法,就可以自定义输出了
当四个接口都实现时,输出的优先级为:
- 如果一个结构体实现了
Formatter
接口,将由该实现控制 - 如果一个结构体实现了
GoStringer
接口,将由该实现控制,不过这个需要配合#
使用 - 如果一个结构体实现了
error
接口,将由该实现控制 - 如果一个结构体实现了
Stringer
接口,将由该实现控制
go
func (p Person) String() string {
return fmt.Sprintf("String: Name is %s, Age is %d", p.Name, p.Age)
}
func (p Person) Error() string {
return fmt.Sprintf("Error: Name is %s, Age is %d", p.Name, p.Age)
}
func (p Person) Format(f fmt.State, verb rune) {
switch verb {
case 'u':
fmt.Fprintf(f, "Format ToUpper: Name is %s, Age is %d", strings.ToUpper(p.Name), p.Age)
case 'l':
fmt.Fprintf(f, "Format ToLower: Name is %s, Age is %d", strings.ToLower(p.Name), p.Age)
default:
fmt.Fprintf(f, "Format Default: Name is %s, Age is %d", p.Name, p.Age)
}
}
func (p Person) GoString() string {
return fmt.Sprintf("GoString: Person{Name: \"%s\", Age: %d}", p.Name, p.Age)
}
对于 %v
来说有效的优先级为:Formatter
> error
> Stringer
go
fmt.Printf("%v\n", person)
对于 %#v
来说有效的优先级为:Formatter
> GoStringer
go
fmt.Printf("%#v\n", person)
Formatter
Formatter
还可以自定义字符,比如 %u
go
func (p Person) Format(f fmt.State, verb rune) {
switch verb {
case 'u':
fmt.Fprintf(f, "Format ToUpper: Name is %s, Age is %d", strings.ToUpper(p.Name), p.Age)
case 'l':
fmt.Fprintf(f, "Format ToLower: Name is %s, Age is %d", strings.ToLower(p.Name), p.Age)
default:
fmt.Fprintf(f, "Format Default: Name is %s, Age is %d", p.Name, p.Age)
}
}
将会命中 case 'u'
分支
go
fmt.Printf("%u\n", person)
环境变量
go
通过 os.Getenv
可以获取到环境变量
go
func main() {
home := os.Getenv("HOME")
fmt.Println("Home directory:", home) // 获取 HOME 环境变量
}
命令行环境变量设置,不能设置已有的环境变量,比如 HOME
go
UCCS="/home" go run .
func main() {
home := os.Getenv("UCCS")
fmt.Println("Home directory:", home)
}
设置临时环境比变量,在命令行输入时临时的,可以把这个命令写入到 ~/.bashrc
中
go
export UCCS="/home"
文件读取
按行读取文件
go
func main() {
file, err := os.Open("example.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, _, err := reader.ReadLine()
if err != nil {
if err == io.EOF { // 读到文件最后,err 为 EOF
break
}
panic(err)
}
fmt.Println(string(line))
}
}
os.Open
和 os.OpenFile
的区别在于:os.Open
只读,os.OpenFile
可以指定读写权限,os.Open
封装了 os.OpenFile
os
文件操作:
os.O_TRUNC
会清空文件内容os.O_APPEND
会在文件末尾追加内容os.O_CREATE
会创建文件os.O_RDONLY
只读os.O_WRONLY
只写os.O_RDWR
读写
用 seek 实现 append
seek
的第一个参数是偏移量,第二个参数是相对位置
- 偏移量为
0
表示相对于当前位置- 偏移量不能传入很大的负数,否则会报错
- 相对位置
io.SeekEnd
表示相对于文件末尾io.SeekStart
表示相对于文件开头io.SeekCurrent
表示相对于当前位置
go
file.Seek(0, io.SeekEnd)
读取目录
ReadDir(-1)
读取所有文件,ReadDir(1)
读取一个文件
go
file, _ := os.OpenFile("test", os.O_RDONLY, 0644)
dirEntries, _ := file.ReadDir(-1)