Open smallnewer opened 8 years ago
在golang和js中的字符串是有些不一样的。在服务器编程中尤其需要注意这点。js中的字符串更符合人类的认知。
在js中部分常见字符串操作:
var str = "abc汉字" str.length; // 5 str[3]; // 汉
golang中
var str = "abc汉字" len(str); // 9 字节长度,utf8下汉字许多是3个字节 str[3]; // 230 按照字节访问
服务器编程中,基本上都提供了对字节进行编程的能力。这块实际上是js缺失的。因此在nodejs中也提供了该能力的Buffer类。看:
> new Buffer("汉") <Buffer e6 b1 89> > parseInt('e6', 16) 230
可以看到汉由三个字节组成,第一个16进制数字转为10进制后成为了230,跟上例golang中的表现一致。
汉
因为在我们的业务逻辑中,很少涉及到底层处理字节的问题。主要对类似js访问字符串的能力更加依赖。所以主要看下这些JS转golang比较痛苦的地方。
真实
上例中len(str)取到的是字节长度,要获取字符串长度的话,首先用到rune数组。 golang中rune更像js中的字符串。
len(str)
str := "abc汉字" a := []rune(str) // 转换成rune数组 len(a) // 5 a[3] // 27721 这里返回的是unicode编码 string(a[3]) // "汉" 需要用这种方式,转换成真实的汉字
rune提供了更类似的js对字符的操作能力。因此在开发中应该比string使用的更多。
但我个人对rune转换性能有疑问,做了个简单的测试
// 7. 获取字符串长度性能 str := "laoYu老虞laoYu老虞laoYu老虞laoYu老虞laoYu老虞" // 方式1,700ns // 5倍长度后,7us st := time.Now() a := []rune(str) // 700ns 慢 fmt.Println("rune time", time.Since(st), len(a)) str1 := "laoYu老虞laoYu老虞laoYu老虞laoYu老虞laoYu老虞" // 方式2,400ns // 5倍长度后,700ns st1 := time.Now() len1 := 0 no := 0 for i, _ := range str1 { len1++ no = i } fmt.Println("range time", time.Since(st1), len1, no)
结论有几点:
在golang和js中的字符串是有些不一样的。在服务器编程中尤其需要注意这点。js中的字符串更符合人类的认知。
在js中部分常见字符串操作:
golang中
服务器编程中,基本上都提供了对字节进行编程的能力。这块实际上是js缺失的。因此在nodejs中也提供了该能力的Buffer类。看:
可以看到
汉
由三个字节组成,第一个16进制数字转为10进制后成为了230,跟上例golang中的表现一致。因为在我们的业务逻辑中,很少涉及到底层处理字节的问题。主要对类似js访问字符串的能力更加依赖。所以主要看下这些JS转golang比较痛苦的地方。
获取字符串的
真实
长度上例中
len(str)
取到的是字节长度,要获取字符串长度的话,首先用到rune数组。 golang中rune更像js中的字符串。rune提供了更类似的js对字符的操作能力。因此在开发中应该比string使用的更多。
但我个人对rune转换性能有疑问,做了个简单的测试
结论有几点: