Entrada e Saída do Go
package main
import "fmt"
func main() {
fmt.Println("Hello 世界!")
}O primeiro exemplo introdutório deste site é a saída de uma string, esta seção explicará como realizar entrada e saída em Go.
Descritores de Arquivo
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)No pacote os existem três descritores de arquivo expostos, todos do tipo *os.File, que são
os.Stdin- entrada padrãoos.Stdout- saída padrãoos.Stderr- erro padrão
A entrada e saída em Go dependem deles.
Saída
Em Go, existem muitos métodos de saída, abaixo estão alguns dos mais comuns
stdout
Como a saída padrão em si é um arquivo, você pode escrever diretamente uma string na saída padrão
package main
import "os"
func main() {
os.Stdout.WriteString("hello world!")
}print
Go tem duas funções incorporadas print, println, elas enviam os parâmetros para o erro padrão, apenas para depuração, geralmente não recomendado usar.
package main
func main() {
print("hello world!\n")
println("hello world")
}fmt
O uso mais comum é usar o pacote fmt, ele fornece a função fmt.Println, que por padrão envia os parâmetros para a saída padrão.
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}Seus parâmetros suportam qualquer tipo, se o tipo implementar a interface String também chamará o método String para obter sua representação em string, então o conteúdo que ele produz tem legibilidade relativamente alta, adequado para a maioria das situações, mas como usa reflexão internamente, não é recomendado usar muito em cenários sensíveis a desempenho.
bufio
bufio fornece métodos de saída com buffer, ele primeiro escreve os dados na memória, acumula até um certo limite e então envia para o Writer especificado, o tamanho padrão do buffer é 4KB. Recomenda-se usar este pacote para IO de arquivos, IO de rede.
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
writer.WriteString("hello world!")
}Você também pode combiná-lo com o pacote fmt
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
fmt.Fprintln(writer, "hello world!")
}Formatação
A funcionalidade de formatação de saída em Go é basicamente fornecida pela função fmt.Printf, se você já aprendeu linguagens da família C, vai achar familiar, abaixo está um exemplo simples.
func main() {
fmt.Printf("hello world, %s!", "jack")
}Abaixo estão todos os verbos de formatação Go atuais.
| 0 | Formatação | Descrição | Tipo de Entrada |
|---|---|---|---|
| 1 | %% | Saída do sinal de porcentagem % | Qualquer |
| 2 | %s | Saída do valor string/[] byte | string,[] byte |
| 3 | %q | Formata string, a string de saída tem aspas duplas "" nos dois lados | string,[] byte |
| 4 | %d | Saída de valor inteiro em decimal | Inteiro |
| 5 | %f | Saída de número de ponto flutuante | Ponto flutuante |
| 6 | %e | Saída em forma de notação científica, também pode ser usado para números complexos | Ponto flutuante |
| 7 | %E | Igual a %e | Ponto flutuante |
| 8 | %g | Julga automaticamente se deve usar %f ou %e para saída, remove zeros desnecessários | Ponto flutuante |
| 9 | %b | Saída da representação binária de inteiro | Número |
| 10 | %#b | Saída da representação binária completa | Número |
| 11 | %o | Saída da representação octal de inteiro | Inteiro |
| 12 | %#o | Saída da representação octal completa de inteiro | Inteiro |
| 13 | %x | Saída da representação hexadecimal minúscula de inteiro | Número |
| 14 | %#x | Saída da representação hexadecimal minúscula completa de inteiro | Número |
| 15 | %X | Saída da representação hexadecimal maiúscula de inteiro | Número |
| 16 | %#X | Saída da representação hexadecimal maiúscula completa de inteiro | Número |
| 17 | %v | Saída do valor na forma original, muito usado para saída de estruturas de dados | Qualquer |
| 18 | %+v | Ao sair struct, adicionará nomes de campos | Qualquer |
| 19 | %#v | Saída do valor em formato de sintaxe Go completo | Qualquer |
| 20 | %t | Saída de valor booleano | Booleano |
| 21 | %T | Saída do tipo Go correspondente ao valor | Qualquer |
| 22 | %c | Saída do caractere correspondente ao código Unicode | int32 |
| 23 | %U | Saída do código Unicode correspondente ao caractere | rune,byte |
| 24 | %p | Saída do endereço apontado pelo ponteiro | Ponteiro |
Use fmt.Sprintf ou fmt.Printf para formatar strings ou sair strings formatadas, veja alguns exemplos
fmt.Printf("%%%s\n", "hello world")
fmt.Printf("%s\n", "hello world")
fmt.Printf("%q\n", "hello world")
fmt.Printf("%d\n", 2<<7-1)
fmt.Printf("%f\n", 1e2)
fmt.Printf("%e\n", 1e2)
fmt.Printf("%E\n", 1e2)
fmt.Printf("%g\n", 1e2)
fmt.Printf("%b\n", 2<<7-1)
fmt.Printf("%#b\n", 2<<7-1)
fmt.Printf("%o\n", 2<<7-1)
fmt.Printf("%#o\n", 2<<7-1)
fmt.Printf("%x\n", 2<<7-1)
fmt.Printf("%#x\n", 2<<7-1)
fmt.Printf("%X\n", 2<<7-1)
fmt.Printf("%#X\n", 2<<7-1)
type person struct {
name string
age int
address string
}
fmt.Printf("%v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%+v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%#v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%t\n", true)
fmt.Printf("%T\n", person{})
fmt.Printf("%c%c\n", 20050, 20051)
fmt.Printf("%U\n", '码')
fmt.Printf("%p\n", &person{})Ao usar outras bases, adicionar um espaço entre % e o verbo de formatação pode obter o efeito de separador, por exemplo
func main() {
str := "abcdefg"
fmt.Printf("%x\n", str)
fmt.Printf("% x\n", str)
}O resultado deste exemplo é
61626364656667
61 62 63 64 65 66 67Ao usar números, também pode-se preencher com zeros automaticamente. Por exemplo
fmt.Printf("%09d", 1)
// 000000001O mesmo vale para binário
fmt.Printf("%09b", 1<<3)
// 000001000Situações de Erro
Quantidade de caracteres de formatação < quantidade da lista de parâmetros
fmt.Printf("", "") //%!(EXTRA string=)Quantidade de caracteres de formatação > quantidade da lista de parâmetros
fmt.Printf("%s%s", "") //%!s(MISSING)Tipo incompatível
fmt.Printf("%s", 1) //%!s(int=1)Falta verbo de formatação
fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)Entrada
Abaixo são apresentados os métodos comuns de entrada
read
Você pode ler o conteúdo de entrada como se estivesse lendo um arquivo diretamente, assim
func main() {
var buf [1024]byte
n, _ := os.Stdin.Read(buf[:])
os.Stdout.Write(buf[:n])
}Usar assim é muito trabalhoso, geralmente não recomendado.
fmt
Podemos usar várias funções fornecidas pelo pacote fmt, o uso é similar ao C.
// Lê o texto de os.Stdin, separa por espaços, nova linha também é considerada espaço
func Scan(a ...any) (n int, err error)
// Similar a Scan, mas para de ler ao encontrar nova linha
func Scanln(a ...any) (n int, err error)
// Lê de acordo com a string de formatação
func Scanf(format string, a ...any) (n int, err error)Lendo dois números
func main() {
var a, b int
fmt.Scanln(&a, &b)
fmt.Printf("%d + %d = %d\n", a, b, a+b)
}Lendo um array de comprimento fixo
func main() {
n := 10
s := make([]int, n)
for i := range n {
fmt.Scan(&s[i])
}
fmt.Println(s)
}1 2 3 4 5 6 7 8 9 10
[1 2 3 4 5 6 7 8 9 10]bufio
Quando há uma grande quantidade de entrada para ler, é recomendado usar bufio.Reader para ler o conteúdo
func main() {
reader := bufio.NewReader(os.Stdin)
var a, b int
fmt.Fscanln(reader, &a, &b)
fmt.Printf("%d + %d = %d\n", a, b, a+b)
}scanner
bufio.Scanner é similar a bufio.Reader, mas lê linha por linha.
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
if line == "exit" {
break
}
fmt.Println("scan", line)
}
}O resultado é o seguinte
first line
scan first line
second line
scan second line
third line
scan third line
exitTIP
Para praticar entrada e saída, se quiser treinar, vá em Luogu fazer alguns exercícios simples de algoritmos em modo ACM para praticar.
