英文:
In Go, can JSON marshaling of a well-defined type ever fail?
问题
给定以下代码:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee")
}
fmt.Println(string(b))
}
在这种情况下,由于Employee
结构已经定义好,可以可靠地使用_
占位符忽略错误检查吗?从理论上讲,它应该永远不会失败,所以问题是忽略这种类型的错误并节省一些样板式的错误检查是否是一个好的做法?
忽略错误的代码如下:
package main
import (
"encoding/json"
"fmt"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, _ := json.Marshal(&Employee{Id: 2})
fmt.Println(string(b))
}
请注意,忽略错误可能会导致潜在的问题,因为你无法得知是否发生了错误。这种做法适用于你确信不会发生错误的情况下,但在一般情况下,建议对错误进行适当的处理和检查。
英文:
Given the following code:
<!-- language: lang-golang -->
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee")
}
fmt.Println(string(b))
}
Can checking for the error be reliably ignored using the _
placeholder since the Employee
struct is well defined. Theoretically it should never fail, so begs the question is it a good practice to ignore this type of error and save a little on this type of boilerplate error checking?
Ignoring would look like so:
<!-- language: lang-golang -->
package main
import (
"encoding/json"
"fmt"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, _ := json.Marshal(&Employee{Id: 2})
fmt.Println(string(b))
}
答案1
得分: 7
> 正确的错误处理是良好软件的基本要求。
通常情况下,你的代码不会出错。但是如果用户将以下MarshalJSON
方法添加到你的类型中,它会出错:
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("禁止的 Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
这段代码可以编译通过,但是故意为了Id == 2
而出错(Go Playground):
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("无法编组 Employee", err)
}
fmt.Println(string(b))
}
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("禁止的 Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
同样,这段代码可以编译通过,但是会出错(Go Playground):
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("无法编组 Employee")
}
fmt.Println(string(b))
}
func (t Employee) MarshalJSON() ([]byte, error) {
data := []byte(fmt.Sprint(t))
return data, nil
}
英文:
> Proper error handling is an essential requirement of good software.
Normally your code won't fail. but if user Adds this MarshalJSON
method reciver to your type, it fails:
<!-- language: lang-golang -->
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("Forbiden Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
This code Compiles, but fails on purpose just for Id == 2
(The Go Playground):
<!-- language: lang-golang -->
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee", err)
}
fmt.Println(string(b))
}
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("Forbiden Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
Also this code Compiles, but fails (The Go Playground):
<!-- language: lang-golang -->
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee")
}
fmt.Println(string(b))
}
func (t Employee) MarshalJSON() ([]byte, error) {
data := []byte(fmt.Sprint(t))
return data, nil
}
答案2
得分: 0
你可以随时编写自己的“包装器”包,以组合可能成为样板代码的行为。例如,如果你已经设置了一个日志系统,你可以构建一个类似下面的小包:
package json
import (
"encoding/json"
"log"
)
func TryMarshal(v interface{}) []byte {
b, err := json.Marshal(v)
if err != nil {
log.Println(err)
return nil
}
return b
}
这个包提供了一个名为TryMarshal
的函数,用于将给定的数据结构转换为JSON格式的字节数组。如果转换过程中出现错误,它会将错误信息记录到日志中,并返回nil
。
英文:
You can always write your own "wrapper" packages to compose behavior that might otherwise be boilerplate. For example, if you have a logging system set up, you might build a small package that looks like:
package json
import (
"encoding/json"
"log"
)
func TryMarshal(v interface{}) []byte {
b, err := json.Marshal(v)
if err != nil {
log.Println(err)
return nil
}
return b
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论