コンテンツにスキップ

Go/uint16

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

Goのuint16について

[編集]

Goにおけるuint16は16ビット符号なし整数型を表す事前に宣言された型です。2バイトのサイズを持ち、0から65535までの値を格納できます。

基本情報

[編集]
  • uint16は16ビット(2バイト)の符号なし整数型
  • 値の範囲: 0 から 65535 (2^16-1)
  • メモリ上での表現: 16ビット
  • ポート番号の表現によく使用される

他のキーワードとの組み合わせ

[編集]

変数宣言との組み合わせ

[編集]
var port uint16 = 8080
count := uint16(1000) // 型推論による短縮形
maxValue := uint16(65535)

定数定義との組み合わせ

[編集]
const DEFAULT_PORT uint16 = 80
const HTTPS_PORT uint16 = 443
const MAX_VALUE uint16 = 65535

関数パラメータと戻り値

[編集]
func validatePort(port uint16) bool {
    return port > 0 && port <= 65535
}

func getRandomPort() uint16 {
    return uint16(8000 + rand.Intn(1000))
}

型変換

[編集]
i := 8080
port := uint16(i) // int から uint16 への変換(値が範囲外の場合は切り捨て)

f := 443.99
port2 := uint16(f) // float から uint16 への変換(小数点以下切り捨て)

// より大きな型からの変換
var bigNum uint32 = 100000
smallNum := uint16(bigNum) // 値が範囲外の場合は下位16ビットのみが保持される

配列とスライス

[編集]
var ports [10]uint16 // uint16型の固定長配列
buffer := make([]uint16, 512) // uint16型のスライス
values := []uint16{80, 443, 8080, 3000, 5432} // リテラルで初期化

マップ

[編集]
serviceports := make(map[string]uint16)
serviceports["http"] = 80
serviceorts["https"] = 443
serviceports["mysql"] = 3306
serviceports["postgresql"] = 5432

構造体のフィールド

[編集]
type ServerConfig struct {
    Host string
    Port uint16
    MaxConnections uint16
}

type NetworkAddress struct {
    IP   [4]uint8 // IPv4アドレス
    Port uint16   // ポート番号
}

ビット操作

[編集]
var flags uint16 = 0
// ビットをセット
flags |= 1 << 8
// ビットをクリア
flags &^= 1 << 5
// ビットをチェック
if (flags & (1 << 8)) != 0 {
    fmt.Println("8番目のビットがセットされています")
}

// 上位8ビットと下位8ビットの分離
var value uint16 = 0x1234
highByte := uint8(value >> 8)  // 0x12
lowByte := uint8(value & 0xFF) // 0x34

一般的なユースケース

[編集]
  1. ネットワークポート番号
       type Server struct {
           Address string
           Port    uint16
       }
       
       func NewServer(address string, port uint16) *Server {
           if port == 0 {
               port = 8080 // デフォルトポート
           }
           return &Server{
               Address: address,
               Port:    port,
           }
       }
    
  2. ID管理(小さな範囲)
       type User struct {
           ID   uint16
           Name string
       }
       
       var userCounter uint16 = 1
       
       func createUser(name string) User {
           user := User{
               ID:   userCounter,
               Name: name,
           }
           userCounter++
           return user
       }
    
  3. バイナリプロトコル処理
       type PacketHeader struct {
           Magic    uint16 // マジックナンバー
           Version  uint16 // プロトコルバージョン
           Length   uint16 // パケット長
           Checksum uint16 // チェックサム
       }
       
       func parseHeader(data []byte) PacketHeader {
           return PacketHeader{
               Magic:    binary.BigEndian.Uint16(data[0:2]),
               Version:  binary.BigEndian.Uint16(data[2:4]),
               Length:   binary.BigEndian.Uint16(data[4:6]),
               Checksum: binary.BigEndian.Uint16(data[6:8]),
           }
       }
    
  4. ゲーム開発での座標
       type Position struct {
           X uint16
           Y uint16
       }
       
       type GameEntity struct {
           ID       uint16
           Position Position
           Health   uint16
       }
       
       func moveEntity(entity *GameEntity, deltaX, deltaY int16) {
           newX := int32(entity.Position.X) + int32(deltaX)
           newY := int32(entity.Position.Y) + int32(deltaY)
           
           // 範囲チェック
           if newX >= 0 && newX <= 65535 {
               entity.Position.X = uint16(newX)
           }
           if newY >= 0 && newY <= 65535 {
               entity.Position.Y = uint16(newY)
           }
       }
    
  5. コンフィグレーション管理
       type DatabaseConfig struct {
           Host            string
           Port            uint16
           MaxConnections  uint16
           TimeoutSeconds  uint16
           RetryAttempts   uint16
       }
       
       func LoadConfig() DatabaseConfig {
           return DatabaseConfig{
               Host:            "localhost",
               Port:            5432,
               MaxConnections:  100,
               TimeoutSeconds:  30,
               RetryAttempts:   3,
           }
       }
    
  6. 画像処理(16ビット深度)
       type Image16Bit struct {
           Width  uint16
           Height uint16
           Pixels []uint16 // 16ビット深度のピクセルデータ
       }
       
       func createImage(width, height uint16) Image16Bit {
           return Image16Bit{
               Width:  width,
               Height: height,
               Pixels: make([]uint16, int(width)*int(height)),
           }
       }
       
       func setPixel(img *Image16Bit, x, y, value uint16) {
           if x < img.Width && y < img.Height {
               index := int(y)*int(img.Width) + int(x)
               img.Pixels[index] = value
           }
       }
    
  7. カウンターとメトリクス
       type Metrics struct {
           RequestCount uint16
           ErrorCount   uint16
           AvgResponse  uint16 // ミリ秒
       }
       
       func incrementMetrics(m *Metrics) {
           if m.RequestCount < 65535 {
               m.RequestCount++
           }
       }
    
  8. バイトオーダー変換
       package main
       
       import (
           "encoding/binary"
           "fmt"
       )
       
       func main() {
           value := uint16(0x1234)
           
           // ビッグエンディアンでバイト配列に変換
           be := make([]byte, 2)
           binary.BigEndian.PutUint16(be, value)
           fmt.Printf("Big Endian: %x\n", be) // [12 34]
           
           // リトルエンディアンでバイト配列に変換
           le := make([]byte, 2)
           binary.LittleEndian.PutUint16(le, value)
           fmt.Printf("Little Endian: %x\n", le) // [34 12]
           
           // バイト配列から読み取り
           restored := binary.BigEndian.Uint16(be)
           fmt.Printf("Restored: 0x%x\n", restored) // 0x1234
       }
    

注意点

[編集]
  1. オーバーフロー: 最大値(65535)を超えると、0に戻ります(ラップアラウンド)
       var x uint16 = 65535
       x++ // x は 0 になる
    
  2. 負の値: 負の値を代入しようとするとコンパイルエラーになります
       var port uint16 = -1 // コンパイルエラー
    
  3. 範囲外の値: 代入時に自動的に切り捨てられます
       var large uint32 = 100000
       var small uint16 = uint16(large) // 100000 % 65536 = 34464
    
  4. 演算時の型昇格: 演算時に型が昇格することがあります
       var a uint16 = 1000
       var b uint16 = 2000
       result := a + b // 型はuint16のまま
       
       // しかし、定数との演算では注意が必要
       var c uint16 = 30000
       // var overflow = c + 40000 // コンパイルエラー(定数がuint16の範囲を超える)
       var safe = c + uint16(40000) // 型変換が必要
    
  5. バイトオーダーの考慮: ネットワーク通信やファイル形式では、バイトオーダー(エンディアンネス)に注意が必要です
       // ネットワークバイトオーダー(ビッグエンディアン)で送信
       func sendUint16(conn net.Conn, value uint16) error {
           buf := make([]byte, 2)
           binary.BigEndian.PutUint16(buf, value)
           _, err := conn.Write(buf)
           return err
       }
    

uint16型は、ポート番号、小規模なID、16ビット深度の画像データなど、中程度の範囲の数値を効率的に扱う場合に適しています。メモリ使用量とデータ範囲のバランスを考慮して適切に選択することが重要です。