作者 主題: [Golang][筆記] 在模擬使用類似 php hash table 時的小陷阱  (閱讀 878 次)

0 會員 與 1 訪客 正在閱讀本文。

Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4913
    • 檢視個人資料
    • http://www.ecmagic.com
php 用習慣了,換個語言來開發總是會想說最好也能夠有支援類似 php 的 hash table
還好 golang 雖然沒有直接支援,不過可以很簡單地定義一個類似的型態來用
例如:

代碼: [選擇]
<?php
error_reporting(0);

$mVal1["k01"] = 12345;
$mVal1["k02"] = "abcdefg";
$mVal1["k03"]["k31"] = 54321;
$mVal1["k03"]["k32"] = "資料123";

var_dump($mVal1);
echo "\$mVal1['k04']['k41']: {$mVal1['k04']['k41']}\n";
?>

在 golang 可以這樣來用

代碼: [選擇]
package main

import (
"fmt"
)

type hash map[string]interface{}

func main() {
mVal1 := make(hash)

mVal1["k01"] = 12345
mVal1["k02"] = "abcdefg"
mVal1["k03"] = make(hash)
mVal1["k03"].(hash)["k31"] = 54321
mVal1["k03"].(hash)["k32"] = "資料123"

fmt.Println("mVal1:", mVal1)
fmt.Println("mVal1[k01]:", mVal1["k01"])
fmt.Println("mVal1[k03]:", mVal1["k03"])
fmt.Println("mVal1[k03][k32]:", mVal1["k03"].(hash)["k32"])
fmt.Println("mVal1[k03][k33]:", mVal1["k03"].(hash)["k33"])

  fmt.Println("mVal1[k04][k42]:", mVal1["k04"].(hash)["k42"])
}

hash 這個自己定義的型態在使用上就有類似 php 陣列的效果
不過,不小心用到未定義過的 key 就掛掉了,像這樣

引用
$ go run ex030.go
mVal1: map[k01:12345 k02:abcdefg k03:map[k31:54321 k32:資料123]]
mVal1[k01]: 12345
mVal1[k03]: map[k31:54321 k32:資料123]
mVal1[k03][k32]: 資料123
mVal1[k03][k33]: <nil>
panic: interface conversion: interface is nil, not main.hash

goroutine 1 [running]:
main.main()
   /home/cpp/go/ex030.go:25 +0xcfe

golang 不會像 php 那樣,使用未定義過的變數就直接空白跳過

雖然麻煩,不過還是有解法:
 
代碼: [選擇]
  //fmt.Println("mVal1[k04][k42]:", mVal1["k04"].(hash)["k42"])
 
  if k04, ok := mVal1["k04"]; ok {
fmt.Println("mVal1[k04][k42]:", mVal1["k04"].(hash)["k42"])
fmt.Println("k04.[k41]", k04.(hash)["k41"])
} else {
mVal1["k04"] = make(hash)
mVal1["k04"].(hash)["k42"] = "新增資料567"
    fmt.Println("mVal1[k04][k41]:", mVal1["k04"].(hash)["k41"])
fmt.Println("mVal1[k04][k42]:", mVal1["k04"].(hash)["k42"])
}

引用
$ go run ex030.go
mVal1: map[k01:12345 k02:abcdefg k03:map[k32:資料123 k31:54321]]
mVal1[k01]: 12345
mVal1[k03]: map[k31:54321 k32:資料123]
mVal1[k03][k32]: 資料123
mVal1[k03][k33]: <nil>
mVal1[k04][k41]: <nil>
mVal1[k04][k42]: 新增資料567

---
在用 json 字串 decode 轉成 map 後就要很小心使用這個 map
不然碰到沒有預期中該有的 key 就會像上面那樣掛了
^__________^