当前位置: 首页 > news >正文

农用地转建设用地结果查询网站苏州品牌网站设计

农用地转建设用地结果查询网站,苏州品牌网站设计,宁阳县住房和城乡建设局网站,做一个网站需要哪些资源Go-知识-fmt 介绍数值类型字符类型布尔类型其他APIFprintPrintSprintFprintf格式穷举PrintfSprintfFprintlnPrintlnSprintln Appendlnerror自定义 Go-知识-fmt 介绍 fmt 实现了格式化输出,并提供了相应的占位符。 支持的数据类型如下: 数值类型&…

Go-知识-fmt

  • 介绍
  • 数值类型
  • 字符类型
  • 布尔类型
  • 其他
  • API
    • Fprint
    • Print
    • Sprint
    • Fprintf
    • 格式穷举
    • Printf
    • Sprintf
    • Fprintln
    • Println
    • Sprintln
  • Appendln
  • error
  • 自定义

Go-知识-fmt

介绍

fmt 实现了格式化输出,并提供了相应的占位符。

支持的数据类型如下:

  • 数值类型:整数类型,浮点类型
  • 字符类型
  • 指针类型
  • 布尔类型
  • 其他

数值类型

  • %b : 二进制
  • %o : 八进制
  • %x : 十六进制
  • %X : 十六进制
  • %d : 十进制
  • %f : 浮点类型
  • %e : 科学计数法
  • %E : 科学计数法

试一试

func TestFmt(t *testing.T) {number := 100.234numberInt := 45fmt.Printf("整数%%d \t %d\n", numberInt)fmt.Printf("八进制%%o \t %o\n", numberInt)fmt.Printf("十六进制%%x \t %x\n", numberInt)fmt.Printf("十六进制%%X \t %X\n", numberInt)fmt.Printf("布尔值%%b \t %b\n", numberInt)fmt.Printf("浮点值%%f \t %f\n", number)fmt.Printf("科学计数法%%e \t %e\n", number)fmt.Printf("科学计数法%%E \t %E\n", number)
}

执行结果如下

image-20250303200412387

字符类型

  • %s : 字符类型
  • %q : 带双引号

如下代码

func TestFmtString(t *testing.T) {str := "hello world"fmt.Printf("字符类型%%s \t %s\n", str)fmt.Printf("待双引号%%q \t %q\n", str)
}

执行结果如下

image-20250303200717948

布尔类型

  • %t : 布尔类型
func TestFmtBool(t *testing.T) {b := truefmt.Printf("布尔类型%%b \t %t\n", b)
}

image-20250303200907588

其他

  • %T : 判断类型(输出类型)
  • %p : 指针类型
  • %v : 默认格式
  • %#v : 带语法的格式
func TestFmtOther(t *testing.T) {a := 1b := 2.0ok := trueptr := &as := struct {Name string}{Name: "test",}fmt.Printf("类型%%T \t %T\n", a)fmt.Printf("类型%%T \t %T\n", b)fmt.Printf("类型%%T \t %T\n", ok)fmt.Printf("类型%%T \t %T\n", ptr)fmt.Printf("类型%%T \t %T\n", s)fmt.Println()fmt.Printf("指针%%p \t %p\n", ptr)fmt.Printf("指针%%p \t %p\n", &a)fmt.Printf("默认格式%%v \t %v\n", s)fmt.Printf("带语法格式%%#v \t %#v\n", s)
}

image-20250303201340465

API

  • Fprint/Fprintf/Fprintln : 带格式的输出
  • Print/Printf/Println : 标准输出
  • Sprint/Sprintf/Sprintln : 格式化内容为 string

Fprint/Print/Sprint 表示使用默认的格式输出或者格式化内容,Fprintf/Printf/Sprintf表示使用指定的格式输出或格式化内容,Fprintln/Println/Sprintln 表示使用默认的格式输出或格式化内容,同时会在最后加上换行符\n

Fprint

源码如下:

// 
func Fprint(w io.Writer, a ...any) (n int, err error) {p := newPrinter()p.doPrint(a)n, err = w.Write(p.buf)p.free()return
}

newPrinter 干了啥

func newPrinter() *pp {p := ppFree.Get().(*pp)p.panicking = falsep.erroring = falsep.wrapErrs = falsep.fmt.init(&p.buf)return p
}

ppFree 又是个啥

var ppFree = sync.Pool{New: func() any { return new(pp) },
}

ppFree 是一个缓存池

image-20250303214241000

提高对象的利用率

p := ppFree.Get().(*pp)是从缓存池中拿一个 pp 结构,因为缓存池是 any 类型的,所以需要进行类型强转

Pp 结构如下:

type pp struct {buf buffer// arg holds the current item, as an interface{}.arg any// value is used instead of arg for reflect values.value reflect.Value// fmt is used to format basic items such as integers or strings.fmt fmt// reordered records whether the format string used argument reordering.reordered bool// goodArgNum records whether the most recent reordering directive was valid.goodArgNum bool// panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.panicking bool// erroring is set when printing an error string to guard against calling handleMethods.erroring bool// wrapErrs is set when the format string may contain a %w verb.wrapErrs bool// wrappedErrs records the targets of the %w verb.wrappedErrs []int
}

有很多的属性

p.fmt.init(&p.buf)设置pp结构的 fmt 的属性

其中的 fmt 结构

type fmt struct {buf *bufferfmtFlagswid  int // widthprec int // precision// intbuf is large enough to store %b of an int64 with a sign and// avoids padding at the end of the struct on 32 bit architectures.intbuf [68]byte
}type fmtFlags struct {widPresent  boolprecPresent boolminus       boolplus        boolsharp       boolspace       boolzero        bool// For the formats %+v %#v, we set the plusV/sharpV flags// and clear the plus/sharp flags since %+v and %#v are in effect// different, flagless formats set at the top level.plusV  boolsharpV bool
}

对于 pp 结构中 fmt 的初始化

func (f *fmt) clearflags() {f.fmtFlags = fmtFlags{}
}func (f *fmt) init(buf *buffer) {f.buf = buff.clearflags()
}

设置了缓存区,同时清空了标志位。因为 pp 的指针值是缓存的,拿出来的可能是之前用过的,所以需要先初始化清空一下才能使用。

p := newPrinter()之后就是 p.doPrint(a) , 看下 doPrint

func (p *pp) doPrint(a []any) {prevString := falsefor argNum, arg := range a {isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String// Add a space between two non-string arguments.if argNum > 0 && !isString && !prevString {p.buf.writeByte(' ')}p.printArg(arg, 'v')prevString = isString}
}

先判断是不是字符串,如果不是字符串,那么在每个值中间加一个 空格

接着调用 printArg 打印

printArg就是针对go支持的所有格式化占位符,进行替换的一个过程

image-20250303215141010

等待占位符替换完成后,将缓存区内的数据,写入到传入的writer里,n, err = w.Write(p.buf)

最后一步的 p.free() 是把从缓存池中拿出来的对象还回去,并且刷新和释放缓存区

func (p *pp) free() {// Proper usage of a sync.Pool requires each entry to have approximately// the same memory cost. To obtain this property when the stored type// contains a variably-sized buffer, we add a hard limit on the maximum// buffer to place back in the pool. If the buffer is larger than the// limit, we drop the buffer and recycle just the printer.//// See https://golang.org/issue/23199.if cap(p.buf) > 64*1024 {p.buf = nil} else {p.buf = p.buf[:0]}if cap(p.wrappedErrs) > 8 {p.wrappedErrs = nil}p.arg = nilp.value = reflect.Value{}p.wrappedErrs = p.wrappedErrs[:0]ppFree.Put(p)
}

Print

Print 就是调用了 Fprint ,只是传入的writer是标准输出设备

func Print(a ...any) (n int, err error) {return Fprint(os.Stdout, a...)
}

Sprint

SprintFprint 差不多,Sprint不需要将缓存区里面的数据写入到 writer了,直接转为字符串返回即可

func Sprint(a ...any) string {p := newPrinter()p.doPrint(a)s := string(p.buf)p.free()return s
}

Fprintf

Fprintf 相比 Fprint 多了一个入参,也就是格式串。格式串就是带有占位符的字符串

func Fprintf(w io.Writer, format string, a ...any) (n int, err error) {p := newPrinter()p.doPrintf(format, a)n, err = w.Write(p.buf)p.free()return
}

其主要逻辑与 Fprint 相同,区别在于 doPrintf

image-20250304200410022

通过 for i := 0; i < end; 循环逐字符解析格式字符串,分为两个处理阶段:

  • 普通字符:直接写入缓冲区
  • 格式化指令:以 % 开头的部分

image-20250304200526710

遇到 % 后执行以下步骤:

  • 解析标志(#, 0, +, -, )
  • 处理参数索引(如 %[3]d)
  • 解析宽度和精度(支持 * 动态值)
  • 处理特殊动词:
    case ‘w’:
    p.wrappedErrs = append(p.wrappedErrs, argNum)
    case ‘v’:
    // 处理 Go 语法格式

image-20250304201135672

参数处理

  • 使用 argNum 跟踪当前参数索引
  • 调用 printArg 进行实际格式化操作
  • 支持参数重排序(%[n] 语法)

image-20250304201233577

  • 错误包装:处理 %w 时记录错误参数位置
  • 类型反射:通过 reflect.Value 处理不同类型
  • 性能优化:使用 buffer 结构进行高效字符串拼接
  • 语法兼容:支持完整的 printf 语法规范

格式穷举

格式串输出示例说明
%v42通用格式,自动匹配类型
%+v{Name: ""}带字段名的结构体输出
%#v"go"Go语法表示值(带类型信息)
%Tfloat64输出值的类型
%d255十进制整数
%b101二进制表示
%o10八进制表示
%xf小写十六进制
%XF大写十六进制
%cAUnicode字符
%f3.141500默认精度浮点数
%.2f3.14保留2位小数
%e1.234500e+03科学计数法表示
%g1.23456789e+08自动选择最紧凑表示法
%shello原始字符串输出
%q"go"带双引号的字符串
%x676f字符串的十六进制编码
%5d 42右对齐宽度5
%-5d42 左对齐宽度5
%05d00042零填充宽度5
%+d+42显示正负号
% d 42正数前留空格
%[2]d %[1]d2 1参数索引重排序
%*d 42动态宽度(参数指定宽度5)
%.*f3.14动态精度(参数指定精度2)
%p0xc0000160a8指针地址
%werror错误包装(需配合errors包使用)
%v[1 2]切片/数组的默认输出
%#v[]int{1, 2}切片/数组的Go语法表示
%+#10.3f +3.142组合格式:符号+宽度10+精度3
%[3]d %[1]s42 hello多参数混合索引
%+v{X:1 Y:2}结构体带字段名输出
%UU+0041Unicode码点格式
%#b0b101Go语法二进制表示
%#o0o10Go语法八进制表示
%#x0xfGo语法十六进制表示
%sMyInt自定义类型实现String()方法时的输出
%d%!d(string=text)类型不匹配时的错误提示
%d%!d(MISSING)缺少参数时的错误提示

Printf

Printf 很简单直接用标准输出调用 Fprintf

func Printf(format string, a ...any) (n int, err error) {return Fprintf(os.Stdout, format, a...)
}

Sprintf

Sprintf 不需要写入write,直接将缓存区的内容返回即可

func Sprintf(format string, a ...any) string {p := newPrinter()p.doPrintf(format, a)s := string(p.buf)p.free()return s
}

Fprintln

Fprintln 基本上也大差不差的,核心是 doPrintln

func Fprintln(w io.Writer, a ...any) (n int, err error) {p := newPrinter()p.doPrintln(a)n, err = w.Write(p.buf)p.free()return
}

doPrintlndoPrint的基础上,在最后加了换行符\n ,都是使用默认格式打印的

func (p *pp) doPrintln(a []any) {for argNum, arg := range a {if argNum > 0 {p.buf.writeByte(' ')}p.printArg(arg, 'v')}p.buf.writeByte('\n')
}

Println

Println 将标准输出作为 writer 请求 Fprintln

func Println(a ...any) (n int, err error) {return Fprintln(os.Stdout, a...)
}

Sprintln

Sprintln 不需要写入writer 直接将缓冲区的内容返回即可

func Sprintln(a ...any) string {p := newPrinter()p.doPrintln(a)s := string(p.buf)p.free()return s
}

Appendln

追加换行

func TestAppln(t *testing.T) {var s []bytes = fmt.Appendln(s, "hello world")s = fmt.Appendln(s, "hello world")s = fmt.Appendln(s, "hello world")fmt.Print(string(s))
}

image-20250304203750503

error

在格式串中 %w 是错误类型的格式串

除此之外,fmt有针对错误的函数Errorf

image-20250304210059103

doPrintf里面会统计 %w的信息

image-20250304210129623

image-20250304210154743

如果只有一个 %w,那么直接使用 errors.New,如果有多个,需要进行warp处理

errors.New 实际上就是 stringError

image-20250304210248207

warpErrors 就是多个错误

image-20250304210322739

自定义

在java等一些语言中,输出调用自动从 Object继承的ToString方法,将对象信息转为字符串。

在go里面也有类似的接口

image-20250304210451478

Stringer 接口定义的String接口就是默认的结构体转字符串的调用方法

type T struct {Name string
}func (t T) String() string {return fmt.Sprintln(fmt.Sprintf("%q", t.Name))
}func TestString(t *testing.T) {name := T{"hello world"}fmt.Print(name)
}

image-20250304210754399

除此之外,还有一个 接口GoStringer 定义的 GoString 用于适配 %#v 才会调用

image-20250304210921969

type T struct {Name string
}func (t T) String() string {return fmt.Sprintln(fmt.Sprintf("%q", t.Name))
}func (t T) GoString() string {return fmt.Sprintln(fmt.Sprintf("struct T :  %q", t.Name))
}func TestString(t *testing.T) {name := T{"hello world"}fmt.Print(name)fmt.Printf("%#v", name)
}

image-20250304211043872

http://www.dtcms.com/a/511022.html

相关文章:

  • 做外贸的网站怎么建立wordpress建网站主页
  • 建设部网站中天人建筑工程有限公司网站设计是怎么做的
  • 网站建设管理工作经验介绍建美食网站有哪些原因
  • 电子商务网站后台功能wordpress thesis 开发
  • 自已做的网站怎么做域名解析沐众科技网站建设
  • 一款app开发需要多少钱郑州seo网络营销技术
  • 做动漫的网站合肥seo公司
  • 免费商城网站制作网站建设制度
  • 网站开发个人博客深圳企业年报网上申报入口
  • 企业营销型网站的内容网站开发设计总结
  • 深圳加盟网站建设wordpress路由正则
  • 陵水网站建设费用深圳还有网站
  • 网站建设的七夕文案国家免费职业培训平台
  • 用帝国cms做门户网站找客户资源的软件
  • 成都网站建设常见问题网站设置英文怎么说
  • 酒店网站建设方案策划seo优化顾问服务
  • 网站制作做站长挣钱网站建设 文库
  • ip域名查询网站入口网站价格评估 优帮云
  • 企业网站建设方案书模板asp.net制作网站开发
  • 做暧暧前戏视频网站wordpress调图片大小
  • 怎么做网站访问截取ip网站的作用
  • 南昌建筑行业网站开发我想自己卖特产怎么做网站
  • cms网站有哪些it人力外包
  • 做平面的网站深圳app开发哪家专业
  • 泉州网站建设费用网络宣传网站建设制作
  • 网站为什么打不开注册开发公司
  • 代做seo关键词排名常州网站关键词优化咨询
  • 金融网站策划方案建设网站观澜
  • 网站收录一般多久广州互联网项目工作室
  • 孝感建设银行官网站牡丹江关键词优化