golang 的那些花样

从 A Tour of Go 可以看到一些 Go 比较特殊的点

文章目录

变量声明时,类型放在后面

go 复制代码
var i, j int = 1, 2

declaration-syntax

Array 的引用 Slice

slices-intro

receiver 和 argument

receiver 习惯用于改变值,尤其是大的struct

go 复制代码
type Vertex struct {
	X, Y float64
}

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

argument 就是method的参数,习惯用于业务逻辑

go 复制代码
type Vertex struct {
	X, Y float64
}

func AbsFunc(v Vertex) float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

receiver 用于实现接口,用于业务逻辑

go 复制代码
type Abser interface {
	Abs() float64
}

func main() {
	var a Abser
	v := Vertex{3, 4}

	a = &v // a *Vertex implements Abser

	fmt.Println(a.Abs())
}

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

built-int特殊接口Error

go 复制代码
package main

import (
	"fmt"
	"math"
)

type ErrNegativeSqrt float64

func (x ErrNegativeSqrt) Error() string {
	return fmt.Sprintf("cannot Sqrt negative number: %f", x)
}

func Sqrt2(x float64) (float64, error) {
	fmt.Println("processing.......")
	if x>0 {
		z := float64(1)
		z = 0.5
		fmt.Println(z)
		for i:=0; math.Abs(z*z -x)>0.00001; i++ {
			z = z - (z*z -x )/(2*z)
			fmt.Println("i", i, "z", z, "z*z -x", z*z -x)
		}
		fmt.Println("finished.")

		return z, nil

	} else {
		return 0, ErrNegativeSqrt(x)
	}

}


func main() {
	fmt.Println(Sqrt2(2))
	fmt.Println(Sqrt2(-2))
}

这里面如果在实现Error接口的时候调fmt.Sprintf用了%v,会再次调x.Error() 进行无限循环, 如果用%v 的话先把值转换出来float64(x)

go 复制代码
func (x ErrNegativeSqrt) Error() string {
	return fmt.Sprintf("cannot Sqrt negative number: %v", float64(x))
}

查看golang源码 https://cs.opensource.google/go/go/+/refs/tags/go1.17:src/fmt/print.go;l=617

go 复制代码
	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
	if p.fmt.sharpV {
		if stringer, ok := p.arg.(GoStringer); ok {
			handled = true
			defer p.catchPanic(p.arg, verb, "GoString")
			// Print the result of GoString unadorned.
			p.fmt.fmtS(stringer.GoString())
			return
		}
	} else {
		// If a string is acceptable according to the format, see if
		// the value satisfies one of the string-valued interfaces.
		// Println etc. set verb to %v, which is "stringable".
		switch verb {
		case 'v', 's', 'x', 'X', 'q':
			// Is it an error or Stringer?
			// The duplication in the bodies is necessary:
			// setting handled and deferring catchPanic
			// must happen before calling the method.
			switch v := p.arg.(type) {
			case error:
				handled = true
				defer p.catchPanic(p.arg, verb, "Error")
				p.fmtString(v.Error(), verb)
				return

			case Stringer:
				handled = true
				defer p.catchPanic(p.arg, verb, "String")
				p.fmtString(v.String(), verb)
				return
			}
		}
	}
	return false
}

A Tour of Go 习题解答

A Tour of Go 习题解答 2

学习字典,随时查

相关推荐
benchmark_cc27 分钟前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
Zenova EdgeOS2 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是2 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
FRing032 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Fatbobman(东坡肘子)3 小时前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift
揽星河..3 小时前
【C语言】底层程序设计
c语言·开发语言
JavaPub-rodert3 小时前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
海的透彻4 小时前
dockerfile如何快速构建容器(java服务)
java·开发语言
code2cat5 小时前
Java工具篇之Gradle:用任务图组织构建与交付
java·开发语言·单元测试·gradle
北京中科新远科技5 小时前
高速交换机端口预算怎么做?下行、上联、拆分和冗余计算框架
开发语言·php