golang_error:error错误输出的两种写法

本文介绍了在Go语言中处理错误的两种常见方法:使用`error.New`创建错误和定义自定义错误类型。通过示例展示了如何根据错误情况进行返回值和错误信息的设置,以及不同情况下输出的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意:

  1. 错误位置中的nil值表示没有错误
  2. if ae, ok := e.(*argError); ok {}
    ae表示argError类型的值,ok表示是否有值。
    “ * ”表示取值,这里要存在

第一种写法:
使用error.New创建error

func f1(arg int) (int, error) {
	if arg == 42 {
		//errors.New对给定的错误信息构造基础的错误值
		return -1, errors.New("can't work with 42")
	}
	return arg + 3, nil
}

func main() {
	for _, i := range []int{7, 42} {
		if r, e := f1(i); e != nil {
			fmt.Println("f1 failed:", e)
		} else {
			fmt.Println("f1 worked:", r)
		}
	}
}

其中 r 和 e 分别表示传出的int和error值

  • 传入值为7时,if判断不执行,return 10,nil。e为nil,打印worked语句
  • 传入值为42时,if判断执行, return -1,can’t work with 42。e不为nil,打印failed语句。

Output:

f1 worked: 10
f1 failed: can't work with 42

第二种写法:
使用一种自定义类型来表示错误

type argError struct {
	arg  int
	prob string
}

func (e *argError) Error() string {
	return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

func f2(arg int) (int, error) {
	if arg == 42 {
		//这里使用&argError新建一个struct,对arg和prob赋值.
		return -1, &argError{arg, "can't work with it"}
	}
	return arg + 3, nil
}

func main() {
	for _, i := range []int{7, 42} {
		if r, e := f2(i); e != nil {
			fmt.Println("f2 failed:", e)
		} else {
			fmt.Println("f2 worked:", r)
		}
	}
	
//如果以编程方式使用自定义错误,可以使用断言进行定义类型

	_, e := f2(42) 
	// e-得到的int和string的值(-1,can't work with it)
	
	if ae, ok := e.(*argError); ok { 
	// ae即为一个argError类型的值。ok是一个bool类型,判断ae取值是否存在,如果存在执行if语句。
	
		fmt.Println(ae.arg)
		fmt.Println(ae.prob)
	}
}
  • 传入值为7时,if语句不执行,return 10,nil。e为nil,打印worked语句。
  • 传入值为42,if语句执行,return -1,42-can’t work with it。e不为nil,打印failed语句。

Output:

f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it
<think>我们正在处理Dockerfile中FROM指令的语法错误,具体错误信息是:“FROMrequireseitheroneorthreearguments”。根据Dockerfile的语法,FROM指令有两种形式:1.FROM<image>[AS<name>]2.FROM<image>[:<tag>][AS<name>]3.FROM<image>[@<digest>][AS<name>]然而,错误信息指出需要“一个或三个参数”,这似乎与上述常见形式不符。实际上,Docker官方文档中说明FROM指令的语法为:-FROM[--platform=<platform>]<image>[:<tag>][AS<name>]-或者(用于多阶段构建)在后续阶段中,可以用之前阶段的名字,如:FROM--stage=<stage_name>...但错误信息提到“一个或三个参数”,这让我们需要重新审视。实际上,错误信息的上下文可能是这样的:如果只提供镜像名称(或者镜像名称与标签),这是一个参数(虽然镜像名称和标签可以视为一个整体,但通常算作一个参数)。而另一种形式是:FROM[--platform=<platform>]<image>[AS<name>],这里实际上有三个部分(platform选项、镜像、ASname),但platform和ASname都是可选的。但是,请注意,Dockerfile解析器将每个单词视为参数。因此,如果我们写成:FROM--platform=linux/amd64alpine:latestASbuild这里,解析器会得到四个参数:'--platform=linux/amd64'、'alpine:latest'、'AS'、'build'。然而,实际上,Docker会解析为:--platform=linux/amd64是一个参数(虽然它包含等号),alpine:latest是第二个参数,ASbuild是另外两个参数(表示阶段名称)。错误产生的原因可能是:1.只写了FROM,后面没有参数。2.写了两个参数,例如:FROMalpinelatest(这会被解析为两个参数:alpine和latest,而正确的应该是alpine:latest作为一个参数)。3.写成了四个或更多参数,但不符合上述三种形式之一。因此,常见的错误写法:-错误:FROMalpinelatest(正确:FROMalpine:latest)-错误:FROMalpineASlatestbuild(正确:FROMalpineASbuild,这里build是阶段名,只能一个单词)另外,错误信息提到“eitheroneorthreearguments”,可能是因为:-一个参数:直接是镜像名称(包含tag或digest)或镜像名称(此时tag默认为latest)作为一个字符串。-三个参数:是指当使用AS时,会看到三个参数:镜像字符串、AS关键字、阶段名字符串。但注意,如果使用了--platform选项,那么选项也算一个参数,这样参数个数就会变多,所以错误信息说“oneorthree”可能是不包括选项的情况。然而,实际上Docker的FROM指令解析并不是简单的按空格分割后的参数个数。但是,根据错误信息,我们可以推断Dockerfile解析器在解析FROM指令时,遇到了它不认可的参数个数(比如2个或者4个以上,且没有正确使用选项或AS子句)。解决步骤:1.检查FROM指令的格式,确保镜像名称(包括标签或摘要)是一个整体。例如,使用`alpine:latest`而不是`alpinelatest`。2.如果使用多阶段构建,确保AS后面只跟一个阶段名(单个单词,且没有空格)。3.检查是否使用了平台选项(--platform),确保其格式正确,且放在FROM之后,镜像名称之前。例如,正确写法:-一个参数:`FROMalpine`-两个参数(使用平台选项,但选项和镜像名称之间没有其他参数):`FROM--platform=linux/amd64alpine`-三个参数:`FROMalpineASbuild`(这里实际上是三个参数:alpine,AS,build)-四个参数:`FROM--platform=linux/amd64alpineASbuild`(四个参数:--platform=linux/amd64,alpine,AS,build)但是这种写法是允许的。然而,错误信息明确指出需要“一个或三个参数”,但上面四个参数的情况也是允许的。因此,错误信息可能有些误导,实际上它可能是指在不使用任何选项的情况下,参数个数必须是1(只有镜像)或3(镜像、AS、阶段名)。如果使用了选项,那么选项会占用一个参数位置,因此会有不同的参数个数。因此,我们应遵循官方文档的写法。如果遇到此错误,请检查:-镜像名称是否包含空格(导致被拆分成多个参数)?-是否在FROM指令中写了不必要的空格(例如,镜像标签应该用冒号而不是空格分隔)?-如果使用AS,是否遗漏了AS关键字或阶段名?根据引用[2],Docker在构建之前会进行语法检查,所以我们可以通过运行`dockerbuild`来验证Dockerfile的语法。下面是一个示例,展示常见的错误和正确写法错误示例1:两个参数FROMalpinelatest->应改为:FROMalpine:latest错误示例2:使用AS但参数个数不对FROMalpineAS->缺少阶段名FROMalpineASbuildstage->阶段名不能包含空格(应该只写一个单词)正确示例:单阶段:FROMalpine:3.12多阶段:FROMalpine:3.12ASbuildstage带平台选项:FROM--platform=linux/amd64alpine:3.12ASbuild另外,注意在引用[1]中提到的例子,Dockerfile的指令是每行一个,且每行只允许一个指令(注释除外)。所以FROM指令必须单独一行。因此,建议检查Dockerfile中FROM指令的书写,确保没有多余的空格,且符合上述格式。如果问题仍然存在,请提供具体的FROM指令行,以便进一步诊断。</think> 根据您遇到的 Dockerfile 错误 `FROM requires either one or three arguments`,以下是详细分析和解决方案: ### 错误原因分析 1. **参数数量错误** `FROM` 指令语法为: - 单参数格式:`FROM <image>[:<tag>]`(例如 `FROM alpine`) - 三参数格式:`FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]`(例如 `FROM --platform=linux/amd64 nginx@sha256:... AS builder`)[^1][^4] 当提供 2 个或 4 个以上参数时(如 `FROM alpine latest`),会触发该错误。 2. **常见错误写法**: ```dockerfile FROM ubuntu:22.04 AS # 缺少阶段名 (仅两个参数) FROM --platform=amd64 nginx latest # 四个参数(实际需合并为 `<image>:<tag>`) ``` ### 解决方案 1. **单镜像基础写法**: ```dockerfile FROM <image>:<tag> # 示例 FROM alpine:3.18 ``` 2. **多阶段构建正确写法**: ```dockerfile FROM [--platform=<平台>] <image>[@<摘要>] AS <阶段名> # 示例 FROM --platform=linux/amd64 golang:1.21 AS builder ``` 3. **带镜像摘要的写法**: ```dockerfile FROM nginx@sha256:2e13d38...8e6d7 AS webserver ``` ### 验证步骤 1. **使用 Docker 语法检查**: 运行命令预检 Dockerfile: ```bash docker build --no-cache - << EOF FROM alpine:3.18 EOF ``` 若返回错误,会明确指示问题行(如 `[1/1] FROM alpine:3.18`)[^2] 2. **转义字符处理**(特殊符号需转义): 在 Windows Dockerfile 首行添加: ```dockerfile # escape=` ``` ### 典型修复案例 **错误配置**: ```dockerfile FROM ubuntu jammy AS build # 错误:4个参数(ubuntu/jammy/AS/build) ``` **正确修正**: ```dockerfile # 方案1:单参数 FROM ubuntu:jammy # 方案2:三参数(多阶段构建) FROM ubuntu:jammy AS build ``` ### 关键注意事项 1. 镜像标签必须用 `:` 连接(非空格分隔) 2. `AS <阶段名>` 必须完整包含阶段名称 3. Windows 路径需双转义:`c:\\directory`[^1] 4. 变量展开需明确:`${VERSION:-latest}`[^4] 通过以上调整即可解决语法错误。Docker 在构建前会进行语法验证,错误消息会明确标识问题行号[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值