ホームページ >バックエンド開発 >Golang >Goでiotaを使用する方法

Goでiotaを使用する方法

藏色散人
藏色散人転載
2021-04-29 11:52:432186ブラウズ

golang の次のチュートリアル コラムでは、Go で iota を使用する方法を紹介します。それが必要な友人に役立つことを願っています。

はじめに

Go 言語は、実際には列挙型キーワードを直接サポートしていません。通常、列挙機能は

const iota を通じて実装されます。

なぜ列挙型を使用する必要があるのか​​と疑問に思う人もいるかもしれません。

stackoverflow には、次のように高く評価された回答があります。

変数 (特にメソッド パラメーター) が小さなセットから 1 つしか取得できない場合は、常に列挙型を使用する必要があります。可能な値の例です。例としては、型定数 (契約ステータス: 「永続」、「一時」、「見習い」)、またはフラグ (「今すぐ実行」、「実行延期」) などがあります。整数の代わりに列挙型を使用する場合 (または文字列コードなど)、コンパイル時のチェックを強化し、無効な定数を渡すことによるエラーを回避し、どの値を使用できるかを文書化します。動作を変更する複数のフラグを受け取る 1 つのメソッドではなく、複数の個別のメソッドがあります)。ただし、フラグや型コードを使用する必要がある場合は、列挙型を使用する方法があります。

簡単に翻訳すると、 2 つのポイント 非常に重要です。

    変数 (特にメソッド パラメーター) が少数の可能な値の 1 つだけを取ることができる場合は、列挙を使用する必要があります。
  • たとえば、定数 (契約ステータス: 正社員、派遣社員、見習い)、またはタスク プログラムを実行する際の即時実行または遅延実行のフラグを入力します。
  • 整数の代わりに列挙型を使用する場合、不正な無効な値が渡されることを回避し、どの値が合法的に使用されているかを記録するために、コンパイル時のチェックが追加されます。

列挙型の実装方法

iota は、Go で事前に宣言されている特別な定数です。 0 として事前宣言されますが、その値はコンパイル段階では固定されません。事前宣言された iota が定数宣言に現れる場合、その値は n 番目の定数の記述にあります。の値は n です (開始値は n です)。 0から)。したがって、同じ型の定数宣言が複数ある場合にのみ意味を持ちます。

たとえば、電子商取引については誰もが知っているように、注文システムには必ず注文ステータスのフローが含まれます。したがって、現時点では、次のようにすることができます。

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota //订单已取消 0  NoPay OrderStatus = iota //未支付  1  PendIng OrderStatus = iota // 未发货 2  Delivered OrderStatus = iota // 已发货 3  Received OrderStatus = iota // 已收货 4)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:0,1}
もちろん、これは非常に面倒に思えます。実際、他の定数は前の行の

iota 式を繰り返すことができ、これを次のように変更できます。

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota //订单已取消 0  NoPay //未支付 1  PendIng // 未发货 2  Delivered // 已发货 3  Received // 已收货 4)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:0,1}
ステータスを表すために値 0 を使用する人はいますか?通常はそうではありません。1 から始めたいので、それで問題ありません。

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota+1 //订单已取消 1
  NoPay //未支付 2  PendIng // 未发货 3  Delivered // 已发货 4  Received // 已收货 5)func main() {
  fmt.Println(Cancelled, NoPay) // 打印:1,2}
また、

Delivered の後の数値 (Received の値、つまり Received=6) もスキップしたいと考えています。はい # 記号を使用します。

package mainimport "fmt"type OrderStatus intconst (
  Cancelled OrderStatus = iota+1 //订单已取消 1
  NoPay //未支付 2  PendIng // 未发货 3  Delivered // 已发货 4  _
 Received // 已收货 6)func main() {
  fmt.Println(Received) // 打印:6}
途中で行うことも、もちろん後ろ向きに行うこともできます。

package mainimport "fmt"type OrderStatus intconst (
  Max = 5)const (
  Received OrderStatus = Max - iota // 已收货  5  Delivered // 已发货 4  PendIng // 未发货 3  NoPay //未支付 2  Cancelled //订单已取消 1)func main() {
  fmt.Println(Received,Delivered) // 打印:5,4}
ビット操作も使用できます。たとえば、go ソース コードの

sync パッケージのロックにこのようなコードがあります。

const (
 mutexLocked = 1 << iota  //1<<0 mutexWoken               //1<<1 mutexStarving            //1<<2 mutexWaiterShift = iota  //3
)

func main() {
 fmt.Println("mutexLocked的值",mutexLocked) //打印:1 fmt.Println("mutexWoken的值",mutexWoken) //打印:2 fmt.Println("mutexStarving的值",mutexStarving) //打印:4 fmt.Println("mutexWaiterShift的值",mutexWaiterShift) // 打印:3}

通常、定数値を直接定義するか、文字列を使用して定数値を表す人もいるかもしれません。

たとえば、

string を使用して上記を表すことができます。実際に、注文ステータスを表すために文字列が使用されているのを見てきました。

package main

import "fmt"

const (
  Cancelled = "cancelled"  NoPay = "noPay"  PendIng = "pendIng"  Delivered = "delivered"  Received = "received")

var OrderStatusMsg = map[string]string{
  Cancelled: "订单已取消",
  NoPay:     "未付款",
  PendIng:   "未发货",
  Delivered: "已发货",
  Received:  "已收货",
}

func main() {
  fmt.Println(OrderStatusMsg[Cancelled])
}

または、整数定数値を直接定義します。

package main

import "fmt"

const (
  Cancelled = 1  NoPay = 2  PendIng = 3  Delivered = 4  Received = 5)

var OrderStatusMsg = map[int]string{
  Cancelled: "订单已取消",
  NoPay:     "未付款",
  PendIng:   "未发货",
  Delivered: "已发货",
  Received:  "已收货",
}

func main() {
  fmt.Println(OrderStatusMsg[Cancelled])
}

実際には、上記の両方が可能ですが、

iota を使用するとさらに利点があります。

    は定数セットの一意性を保証できますが、人為的な定義では保証できません。
  • アクションのグループに対して同じ動作を共有できます。
  • 無効な値は避けてください。
  • コードの可読性とメンテナンス性を向上させます。

Extension

上記で示したとおり、最終的にこれを行うことができます。

package main

import (
 "fmt")

type OrderStatus int

const (
  Cancelled OrderStatus = iota + 1 //订单已取消 1  NoPay //未支付 2  PendIng // 未发货 3  Delivered // 已发货 4  Received // 已收货 5)

//公共行为 赋予类型 String() 函数,方便打印值含义
func (order OrderStatus) String() string { return [...]string{"cancelled", "noPay", "pendIng", "delivered", "received"}[order-1]
}

//创建公共行为 赋予类型 int 函数 EnumIndex()
func (order OrderStatus) EnumIndex() int { return int(order)
}

func main() {
 var order OrderStatus = Received
  fmt.Println(order.String())    // 打印:received
  fmt.Println(order.EnumIndex()) // 打印:5
}

概要

この記事では、主に

Golang での iota の使用法と、それを使用する必要がある理由を紹介します。

このようなシーンであなたが普段どのようなテクニックを使っているのかわかりません。以下にメッセージを残して交換してください。

以上がGoでiotaを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。