为什么fmt.Printf在Go中接受%x的字节数组

Hot*_*PxL 6 go

我是Go的新手.我想知道数组和切片之间的确切区别,所以如果我对规范过于痴迷,请原谅我.

在对包的文档fmt,它说的Printf%x可以接受的字节串和切片.它没有说明字节数组.但事实上,如果我在其中放入一个字节数组,它打印出来也很好!

package main

import (
  "fmt"
)

func main() {
  var b [6]byte
  for i := 0; i < 6; i++ {
    b[i] = 'a'
  }
  fmt.Printf("%s\n", b) // "aaaaaa"
}
Run Code Online (Sandbox Code Playgroud)

谁能告诉我为什么?AFAIK,字节数组和切片不能隐式转换为彼此.

感谢您阅读我的问题!

Nic*_*ood 9

你是不正确的,你不能隐式转换切片和数组.

切片是一个小数据结构,有3个元素,它们是指向某个内存的指针,内存的长度和内存的容量.

然而,数组只是一块内存.

Go通过函数中的值传递所有内容,这意味着当您Printf使用数组调用时,数组的整个内存都将传递给函数.当您使用切片调用它时,将传递整个切片结构Printf.但是,切片结构包含指向底层内存的指针,因此这非常类似于将指针传递给数组.

Printf使用大量的内省来打印它的价值观.所有参数Printf都转换为interface{}类型,这意味着它们被装在一个小结构中. Printf然后检查这些接口值,检查类型并找出如何打印值.对于大多数不支持的%类型,Printf它可能需要很多类型,并尝试以用户友好的方式打印它们.

例如,%x可以采用int以十六进制打印的形式,或者您发现的切片或数组.

所以总结一下

  • 数组连续的内存
  • slice是一个包含指向连续内存的指针的结构
  • 接口值是一个包含指向类型和值的指针的小结构
  • Printfinterface{}
  • interface{}反映了价值观,印刷了许多不同的东西

我希望这个解释很有帮助!