検索

Go の JSON

May 11, 2018 pm 06:00 PM



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"`}
場合によっては、PHP など以前 (弱い Type 言語)、Age の値は "Age": "30" になる可能性があります。この形式は互換性のために Go に実装されるか、Price などの浮動小数点値がクライアントに返される可能性があります。精度の問題がある場合、クライアントはそれを表示し、浮動小数点値の文字列を返すだけです。この状況では、タグ「json:”,string”」を追加するだけで済みます。ここでのカンマの後の「文字列」はタグのオプションです。

特定のフィールドを無視したい場合は、`json:”-”` を追加します。値が空の場合に無視したい場合は、`json:”,omitempty” のように、omitempty オプションを追加します。 `

デコード時には、エクスポートされた構造体フィールドのタグとの一致が優先され、次にフィールド、最後に大文字と小文字を区別しないさまざまな形式のフィールド (NAME/NAme などと一致する名前など) が優先されます。 。

2) MarshalIndent 関数

この関数の機能は Marshal と同じですが、人間が読みやすいように json をフォーマットするだけです。この関数が上記の例で使用された場合、MarshalIndent(person, “”, “t”) の出力は次のようになります:

{    "Name": "polaris",    "Age": 30,    "Price": 3.4}
3) エンコーダーとデコーダー

場合によっては、 Request などから開始することもできます。解析のために入力ストリームから json を直接読み取るか、エンコードされた json を直接出力します。便宜上、標準ライブラリには Decoder タイプと Encoder タイプが用意されています。これらはそれぞれ io.Reader および io.Writer を通じてインスタンス化され、それらからデータを読み書きします。

ソース コードを読むと、Encoder.Encode/Decoder.Decode と Marshal/Unmarshal の実装がほぼ同じであることがわかります。いくつかの違いがあります。Decoder にはメソッド UseNumber があり、その関数は次のとおりです。デフォルトでは、json の数が Go で float64 にマッピングされます。これにより、次のような問題が発生することがあります。

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))
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.Number 型を使用しました。

4) RawMessage 型

この型の定義は、RawMessage []byte 型です。元の json オブジェクトが保存されており、遅延する可能性があることがわかります。 json のデコード。使用例については、http://docs.studygolang.com/pkg/encoding/json/#RawMessage の例を参照してください。

5) 他の関数やタイプ (エラー タイプなど) は一般的に使用されないため、ここでは説明しません。公式ドキュメントを直接参照してください。

2. 実際のアプリケーションの問題

クライアントとサーバーが json データ形式を使用して通信する場合、一方ではクライアントの json データをデコードする必要があります。 jsonをエンコードしてクライアントに送信します。

一般的,服务器发送给客户端的 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 来优化性能。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPセッションを失敗させる可能性のあるいくつかの一般的な問題は何ですか?PHPセッションを失敗させる可能性のあるいくつかの一般的な問題は何ですか?Apr 25, 2025 am 12:16 AM

PHPSESSIONの障害の理由には、構成エラー、Cookieの問題、セッションの有効期限が含まれます。 1。構成エラー:正しいセッションをチェックして設定します。save_path。 2.Cookieの問題:Cookieが正しく設定されていることを確認してください。 3.セッションの有効期限:セッションを調整してください。GC_MAXLIFETIME値はセッション時間を延長します。

PHPでセッション関連の問題をどのようにデバッグしますか?PHPでセッション関連の問題をどのようにデバッグしますか?Apr 25, 2025 am 12:12 AM

PHPでセッションの問題をデバッグする方法は次のとおりです。1。セッションが正しく開始されるかどうかを確認します。 2.セッションIDの配信を確認します。 3.セッションデータのストレージと読み取りを確認します。 4.サーバーの構成を確認します。セッションIDとデータを出力し、セッションファイルのコンテンツを表示するなど、セッション関連の問題を効果的に診断して解決できます。

session_start()が複数回呼び出されるとどうなりますか?session_start()が複数回呼び出されるとどうなりますか?Apr 25, 2025 am 12:06 AM

session_start()への複数の呼び出しにより、警告メッセージと可能なデータ上書きが行われます。 1)PHPは警告を発し、セッションが開始されたことを促します。 2)セッションデータの予期しない上書きを引き起こす可能性があります。 3)session_status()を使用してセッションステータスを確認して、繰り返しの呼び出しを避けます。

PHPでセッションのライフタイムをどのように構成しますか?PHPでセッションのライフタイムをどのように構成しますか?Apr 25, 2025 am 12:05 AM

PHPでのセッションライフサイクルの構成は、session.gc_maxlifetimeとsession.cookie_lifetimeを設定することで達成できます。 1)session.gc_maxlifetimeサーバー側のセッションデータのサバイバル時間を制御します。 0に設定すると、ブラウザが閉じているとCookieが期限切れになります。

セッションを保存するためにデータベースを使用することの利点は何ですか?セッションを保存するためにデータベースを使用することの利点は何ですか?Apr 24, 2025 am 12:16 AM

データベースストレージセッションを使用することの主な利点には、持続性、スケーラビリティ、セキュリティが含まれます。 1。永続性:サーバーが再起動しても、セッションデータは変更されないままになります。 2。スケーラビリティ:分散システムに適用され、セッションデータが複数のサーバー間で同期されるようにします。 3。セキュリティ:データベースは、機密情報を保護するための暗号化されたストレージを提供します。

PHPでカスタムセッション処理をどのように実装しますか?PHPでカスタムセッション処理をどのように実装しますか?Apr 24, 2025 am 12:16 AM

PHPでのカスタムセッション処理の実装は、SessionHandlerInterfaceインターフェイスを実装することで実行できます。具体的な手順には、次のものが含まれます。1)CussentsessionHandlerなどのSessionHandlerInterfaceを実装するクラスの作成。 2)セッションデータのライフサイクルとストレージ方法を定義するためのインターフェイス(オープン、クローズ、読み取り、書き込み、破壊、GCなど)の書き換え方法。 3)PHPスクリプトでカスタムセッションプロセッサを登録し、セッションを開始します。これにより、データをMySQLやRedisなどのメディアに保存して、パフォーマンス、セキュリティ、スケーラビリティを改善できます。

セッションIDとは何ですか?セッションIDとは何ですか?Apr 24, 2025 am 12:13 AM

SessionIDは、ユーザーセッションのステータスを追跡するためにWebアプリケーションで使用されるメカニズムです。 1.ユーザーとサーバー間の複数のインタラクション中にユーザーのID情報を維持するために使用されるランダムに生成された文字列です。 2。サーバーは、ユーザーの複数のリクエストでこれらの要求を識別および関連付けるのに役立つCookieまたはURLパラメーターを介してクライアントに生成および送信します。 3.生成は通常、ランダムアルゴリズムを使用して、一意性と予測不可能性を確保します。 4.実際の開発では、Redisなどのメモリ内データベースを使用してセッションデータを保存してパフォーマンスとセキュリティを改善できます。

ステートレス環境(APIなど)でセッションをどのように処理しますか?ステートレス環境(APIなど)でセッションをどのように処理しますか?Apr 24, 2025 am 12:12 AM

APIなどのステートレス環境でのセッションの管理は、JWTまたはCookieを使用して達成できます。 1。JWTは、無国籍とスケーラビリティに適していますが、ビッグデータに関してはサイズが大きいです。 2.cookiesはより伝統的で実装が簡単ですが、セキュリティを確保するために慎重に構成する必要があります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール