| 
1 | 1 | ##10.2 本地化资源  | 
 | 2 | +前面小节我们介绍了如何设置Locale,设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢?这里面的信息包括:文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们讲对这些信息一一进行介绍,Go语言中我们把这些格式信息存储在JSON中,然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.json)  | 
2 | 3 | ##本地化文本消息  | 
 | 4 | +文本信息是我们编写Web应用中最长用到的,也是本地化资源中最多的信息,你想要以适合本地的语言显示文本信息,那么就需要建立相应的map来维护一个key-value的关系,在打印消息之前从map中去获取相应的字符串,例如下面这个例如,一个包含英文和中文的食品名称的简单的map,以及一个从该map中抽取单词的函数。  | 
 | 5 | + | 
 | 6 | +	package main  | 
 | 7 | + | 
 | 8 | +	import "fmt"  | 
 | 9 | + | 
 | 10 | +	var locales map[string]map[string]string  | 
 | 11 | + | 
 | 12 | +	func main() {  | 
 | 13 | +		locales = make(map[string]map[string]string, 2)  | 
 | 14 | +		en := make(map[string]string, 10)  | 
 | 15 | +		en["pea"] = "pea"  | 
 | 16 | +		en["bean"] = "bean"  | 
 | 17 | +		locales["en"] = en  | 
 | 18 | +		cn := make(map[string]string, 10)  | 
 | 19 | +		cn["pea"] = "豌豆"  | 
 | 20 | +		cn["bean"] = "毛豆"  | 
 | 21 | +		locales["zh-CN"] = cn  | 
 | 22 | +		lang := "zh-CN"  | 
 | 23 | +		fmt.Println(msg(lang, "pea"))  | 
 | 24 | +		fmt.Println(msg(lang, "bean"))  | 
 | 25 | +	}  | 
 | 26 | + | 
 | 27 | +	func msg(locale, key string) string {  | 
 | 28 | +		if v, ok := locales[locale]; ok {  | 
 | 29 | +			if v2, ok := v[key]; ok {  | 
 | 30 | +				return v2  | 
 | 31 | +			}  | 
 | 32 | +		}  | 
 | 33 | +		return ""  | 
 | 34 | +	}  | 
 | 35 | + | 
 | 36 | + | 
 | 37 | +上面实现了简单的不同locale的文本翻译,实现了中文和英文对于同一个key显示不同的语言,上面实现了中文语言的文本消息,如果想切换到英文版本,只需要把lang设置问en即可。  | 
 | 38 | + | 
 | 39 | +但是有些时候并不是简单的key-value就能实现所有的文本翻译的,例如"I am 30 years old",中文表达是"我今年30岁了",而这个30是一个变量,这个时候我们可以结合`fmt.Printf`函数来实现,请看下面的代码:  | 
 | 40 | + | 
 | 41 | +	en["how old"] ="I am %d years old"  | 
 | 42 | +	cn["how old"] ="我今年%d岁了"  | 
 | 43 | + | 
 | 44 | +	fmt.Printf(msg(lang, "how old"), 30)  | 
 | 45 | + | 
 | 46 | +上面的示例代码主要是为了演示我们内部实现的思路,其实最后数据是存储在JSON里面的,map我们可以通过`json.Unmarshal`获取对应的数据。  | 
 | 47 | +	  | 
3 | 48 | ##本地化日期和时间  | 
 | 49 | +时间和日期对于不同的地区会显示不同的时间点,而且相应的显示时间格式也是不同的,例如中文环境下可能显示:`2012年10月24日 星期三 23时11分13秒 CST`,而在英文环境下可能显示:`Wed Oct 24 23:11:13 CST 2012`。这里面我们需要解决两点:  | 
 | 50 | + | 
 | 51 | +1. 时区问题  | 
 | 52 | +2. 格式问题  | 
 | 53 | + | 
 | 54 | +时区问题我们可以通过`time.Now`返回当前locale的时间,但是我们可以通过`time.LoadLocation(name string)`获取相应地区的时区,如果中文地区,那么`name=Asia/Shanghai`,如果在美国那么可以设置`name=America/Chicago`,你可以在`$GOROOT/lib/time`包中找到time.zip,里面有每个地区的时区定义。详细的请看下面的例子:  | 
 | 55 | + | 
 | 56 | +	en["time_zone"]="America/Chicago"  | 
 | 57 | +	cn["time_zone"]="Asia/Shanghai"  | 
 | 58 | +	  | 
 | 59 | +	loc,_:=time.LoadLocation(msg(lang,"time_zone"))  | 
 | 60 | +	t:=time.Now()  | 
 | 61 | +	t = t.In(loc)  | 
 | 62 | +	fmt.Println(t.Format(time.RFC3339))  | 
 | 63 | + | 
 | 64 | +格式问题我们可以通过类似上面文本信息的方式解决这个问题,就如上面刚开始显示的时间格式一样,中文和英文的显示信息完全不同,那我们就可以通过如下方式来实现  | 
 | 65 | + | 
 | 66 | +	en["date_format"]="%Y-%m-%d %H:%M:%S"  | 
 | 67 | +	cn["date_format"]="%Y年%m月%d日 %H时%M分%S秒"  | 
 | 68 | +	  | 
 | 69 | +	fmt.Println(date(msg(lang,"date_format"),t))  | 
 | 70 | +	  | 
 | 71 | +	func date(fomate string,t time.Time) string{  | 
 | 72 | +		year, month, day = t.Date()  | 
 | 73 | +		hour, min, sec = t.Clock()  | 
 | 74 | +		//解析相应的%Y %m %d %H %M %S然后返回信息  | 
 | 75 | +		//%Y 替换成2012  | 
 | 76 | +		//%m 替换成10  | 
 | 77 | +		//%d 替换成24  | 
 | 78 | +	}  | 
 | 79 | + | 
4 | 80 | ##本地化货币值  | 
5 |  | -##本地化图像  | 
 | 81 | +各个地区的货币表示也不一样,我们想要根据不同的Locale显示不同的货币金额需要实现如上时间格式的处理函数,详细的实现请看下面代码:  | 
 | 82 | + | 
 | 83 | +	en["money"] ="USD %d"  | 
 | 84 | +	cn["money"] ="¥%d元"  | 
 | 85 | + | 
 | 86 | +	fmt.Println(date(msg(lang,"date_format"),100))  | 
 | 87 | +	  | 
 | 88 | +	func money_format(fomate string,money int64) string{  | 
 | 89 | +		return fmt.Sprintf(fomate,money)  | 
 | 90 | +	}  | 
 | 91 | +	  | 
 | 92 | + | 
 | 93 | +##本地化图片  | 
6 | 94 | ##本地化包含文件  | 
7 | 95 | ##管理本地化资源  | 
8 | 96 | ## links  | 
 | 
0 commit comments