Go の JSON
PHP を使用したことがある人なら誰でも、PHP が JSON データを処理するのに非常に便利であることを知っています。json_encode と json_decode という 2 つの関数がすべてを処理します。では、Go で JSON を扱うにはどうすればよいでしょうか?
1. エンコーディング/json 標準ライブラリ
json ライブラリを学ぶには、まず Go の struct タグ、reflect などの知識を理解する必要があります。
1. 概要
json パッケージは、json オブジェクトのエンコードとデコードを実装します。RFC 4627 を参照してください。 Json オブジェクトと go 型の間のマッピング関係については、Marshal 関数と Unmarshal 関数のドキュメントを参照してください。
このパッケージの概要については、「JSON と Go」を参照してください。
2. 主要な関数と型
関数と型については、頻繁に使用されるものに焦点を当てます。
1) Marshal と Unmarshal
これら 2 つは、最も一般的に使用される関数であり、json オブジェクトのエンコードとデコードです。これら 2 つの関数のドキュメントは非常に長く、Go 型と json オブジェクトの間のマッピング関係が詳細に説明されています。マッピング関係は次のように構成されます:
bool、JSON ブール値の場合
float64、JSON 数値の場合
string、JSON 文字列の場合
[]interface {}、JSON 配列の場合
map[string]interface{}、JSON オブジェクトの場合
JSON null の場合 nil
詳細なエンコードとデコードのルールについては、「
①デフォルトでは、上記のマッピングに従って解析されます。
②オブジェクトが json.Marshaler/Unmarshaler インターフェイスを実装している場合、そうでない場合。 nil ポインターの場合、対応するメソッドがエンコードとデコードに使用されます。インターフェースが実装されていないが、encoding.TextMarshaler/TextUnmarshaler インターフェースが実装されている場合は、エンコードとデコードにインターフェースの対応するメソッドが呼び出されます。 >
③構造体は、関連するエンコードとデコードを制御するために「json」タグを使用します。④構造体の匿名フィールドはデフォルトで展開されます。展開されないようにタグを指定できます。 ; ⑤匿名フィールドがある場合、同じレベル名に同じフィールドが存在する場合、競合は発生せず、特定の処理ルール文書には ⑥ をデコードするとき。構造体、冗長フィールド、または存在しないフィールド (エクスポートされていないフィールドを含む) は、エラーを報告せずに無視されます。また、Unmarshal に渡される 2 番目のパラメーターはポインターである必要があることに注意してください。 使用例:
package mainimport ( "encoding/json" "fmt")func main() { type Book struct { Name string Price float64 // `json:"price,string"` } var person = struct { Name string Age int Book }{ Name: "polaris", Age: 30, Book: Book{ Price: 3.4, Name: "Go语言", }, } buf, _ := json.Marshal(person) fmt.Println(string(buf)) // Output:{"Name":"polaris","Age":30,"Price":3.4} // Book 中的 Name 被忽略了}
var person = struct { Name string Age int Book `json:"Book"`}
{ "Name": "polaris", "Age": 30, "Price": 3.4}
b := []byte(`{"Name":"polaris","Age":30,"Money":20.3}`)var person = make(map[string]interface{})err := json.Unmarshal(b, &person)if err != nil { log.Fatalln("json unmarshal error:", err)}age := person["Age"]log.Println(age.(int))
Decoder.Decode に変更しました (UseNumber を使用) 試してみます:
b := []byte(`{"Name":"polaris","Age":30,"Money":20.3}`)var person = make(map[string]interface{})decoder := json.NewDecoder(bytes.NewReader(b))decoder.UseNumber()err := decoder.Decode(&person)if err != nil { log.Fatalln("json unmarshal error:", err)}age := person["Age"]log.Println(age.(json.Number).Int64())
一般的,服务器发送给客户端的 json 数据,是通过 struct、[]struct 或 map[string]interface{} 等编码得到。这里除了上文说到的,可能需要对数值类型使用 string tag options 之外,对于 time.Time 类型(实现了Marshaler 接口),默认编码得到的时间格式是:RFC3339即2006-01-02T15:04:05Z07:00,很多时候客户端可能不希望得到这样的时间,他们更多时候只是需要一个可读的时间字符串,如 2006-01-02 15:04:05。对此,我们可以定义自己的类型 type OftenTime time:
func (self OftenTime) MarshalJSON() ([]byte, error) { t := time.Time(self) if y := t.Year(); y < 0 || y >= 10000 { return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") } return []byte(t.Format(`"2006-01-02 15:04:05"`)), nil}func (this *OftenTime) UnmarshalJSON(data []byte) (err error) { t := time.Time(*this) return t.UnmarshalJSON(data)}
另外,有一个坑,json 对象的 key 必须是字符串,所以 map[int]interface{} 在编码时会报错,错误是 json.UnsupportedTypeError.
对于接收客户端数据,进行 json 解码,遇到的问题可能比较多,特别是同时接收多种语言的数据,比如 PHP、Java 等。比如 b := []byte(`{“Name”:”polaris”,”Age”:30,”Money”:20.3}`),PHP 传递过来的可能是:b := []byte(`{“Name”:”polaris”,”Age”:”30″,”Money”:”20.3″}`),在使用 struct 接收数据时,对于 Age,如果是 int,我们可以直接定义为 int 类型,但如果是string,可以通过 string tag options 接收;但如果Age有时是 int, 有时是 string,就会出问题。最理想的情况,当然是不希望出现这种情况,但有一点,程序要保证出现这种情况时,不能 panic。
在实际应用中,我就遇到了上面的问题,于是,自己写了一个 json 解析,能支持自动类型转换。代码开源在 github: https://github.com/polaris1119/jsonutils
三、性能问题
很明显,json 的编解码,使用了 Go 的反射功能,所以,性能自然不是太好,正因为如此,有了 ffjson、easyjson 之类的开源库(在 github 上),它们的原理是通过 go generate 根据 struct 生成相应的代码,避免反射。如果你对性能要求比较高,但又不想使用msgpack/pb/thrift 之类的,那么可以考虑使用 ffjson/easyjson 来优化性能。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

セッションハイジャックは、次の手順で達成できます。1。セッションIDを取得します。2。セッションIDを使用します。3。セッションをアクティブに保ちます。 PHPでのセッションハイジャックを防ぐための方法には次のものが含まれます。1。セッション_regenerate_id()関数を使用して、セッションIDを再生します。2。データベースを介してストアセッションデータを3。

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。
