Skip to content

Commit

Permalink
New blog: nz-holiday-park-1
Browse files Browse the repository at this point in the history
  • Loading branch information
lingxiankong committed Feb 27, 2019
1 parent 550e3a9 commit bd188d1
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 6 deletions.
80 changes: 74 additions & 6 deletions _posts/技术/2016-12-20-go-note.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ go clean,代码提交前清除当前源码包和关联源码包里面编译生

测试某个类:
`go test -v -test.run TestMain`
`/usr/local/go/bin/go test -timeout 30s github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/l7policies/testing -run ^TestRequiredRuleCreateOpts$`
`go test -timeout 30s github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/l7policies/testing -run ^TestRequiredRuleCreateOpts$`

## 安装和试用
> [这里](https://github.com/dims/openstack-cloud-controller-manager/blob/7c103775b118a9dfc3b33b112d5de17389fd82bf/tools/test-setup.sh)有一个安装脚本,安装 go 1.9以及 glide
Expand Down Expand Up @@ -69,10 +69,10 @@ apt-get install -y bison ed gawk gcc libc6-dev make
cd -
```

安装脚本
在 ubuntu 上安装 go 的脚本

```shell
curl -SL https://gist.githubusercontent.com/lingxiankong/ad724e785abd133632cc604210b45659/raw/de29e5dbe1ad597891b40c3862a118d05be11da8/install_go.sh -o ~/install_go.sh && source ~/install_go.sh 1.10.4
sudo curl -SL# https://gist.github.com/lingxiankong/ad724e785abd133632cc604210b45659/raw/4d6849bb3388ec0c8638b2d9422d6471c53ba646/install_go.sh -o ~/install_go.sh && source ~/install_go.sh 1.10.4
```

或者借助 [gimme](https://github.com/travis-ci/gimme) 安装:
Expand Down Expand Up @@ -168,15 +168,39 @@ main包中的main函数既没有参数,也没有返回类型(与C家族中

### 变量
- 浮点数的类型有float32和float64两种(没有float类型),默认是float64。

- `var _ I = T{}`,这个语句其实在测试结构体T是否实现了接口I,下划线忽略变量名

- [reflect](http://www.nljb.net/default/Golang%E4%B9%8BReflect%E4%BD%BF%E7%94%A8%E4%BB%8B%E7%BB%8D/)
- 在一个变量上调用 reflect.TypeOf() 可以获取变量的正确类型
- `reflect.ValueOf(s)` 获取对象的值

- 声明数组:`var arr1 [5]int`,数组的初始化有很多种方式(比如自动计算长度:`var arr1 [...]int{1,2,3}`),数组是值类型,数组的长度的固定的,可以通过传递数组的引用在函数中修改数据。用 for...range 的方式迭代数组会更安全,每轮迭代对数组元素访问时可以不用判断下标越界。

- 声明切片:`var slice1 []type`,不需要说明长度,初始化:`var slice1 []type = arr1[start:end]`,切片是引用类型。切片类似于Python中的list,切片使用make() 创建。切片的cap就相当于数组的长度。切片在内存中的组织方式实际上是一个有 3 个域的结构体:指向相关数组的指针,切片长度以及切片容量。当相关数组还没有定义时,可以使用 make() 函数来创建一个切片同时创建好相关数组:`var slice1 []type = make([]type, len)`
- 声明 map:`var map1 map[string]int`,map 是引用类型,用 make() 创建。判断一个map中是否存在某个key:`val1, isPresent = map1[key1]`。map 不是thread-safe,在多个go-routine存取时,必须使用mutex lock机制

- [map](https://blog.golang.org/go-maps-in-action)

```go
// map 是引用类型,用 make() 创建
var map1 map[string]int
map1 = make(map[string]int)
// 或者直接
map1 := make(map[string]int)

// 判断一个map中是否存在某个key
if val1, isPresent = map1[key1]; isPresent {}

// 删除一个 key
delete(m, "route")
```

- map 不是thread-safe,在多个go-routine存取时,必须使用mutex lock机制

- new 和 make 的区别:make 只能用于 slice,map,channel 三种内建引用类型。new适用于值类型如数组和结构体的内存分配。new(T) 分配零值填充的T类型的内存空间,返回的是 T 的指针,

- `var x interface{} = nil`

- 对于使用`:=`定义的变量,如果新变量p与同名已定义变量 (这里就是那个全局变量p)不在一个作用域中时,那么golang会新定义这个变量p,遮盖住全局变量p

### 函数
Expand Down Expand Up @@ -225,7 +249,7 @@ Go支持的代码结构语句:

* switch

python 没有 switch。switch无需使用break退出分支,默认行为是匹配到一个分支运行结束后,就退出switch语句。如果希望继续执行,使用fallthrough
python 没有 switch。switch无需使用break退出分支,默认行为是匹配到一个分支运行结束后,就退出switch语句。如果希望继续执行,使用 fallthrough

* select

Expand Down Expand Up @@ -542,13 +566,34 @@ go func(doneCh chan<- bool) {

### 字符串 string

- k8s 提供的一个 sets 库:

```go
import "k8s.io/apimachinery/pkg/util/sets"
// - 获取 map 到 keys
```

- [strings](https://golang.org/pkg/strings/),[介绍](http://www.cnblogs.com/golove/p/3236300.html)

```go
tagsString := strings.Join(tags, ",")
```

- 使用[fmt.Printf](https://gobyexample.com/string-formatting),换行需要加`\n`,`%v`代表使用类型的默认输出格式,`%#v` 提供最典型的调试信息,`%t`表示布尔型,`%g`表示浮点型,`%p`表示指针。int 不能使用 %s 打印,必须是%d

- python 里面的原生字符串(比如`r('xxx')`)在 go 中用反引号表示。

- 什么时候用 `string` 什么时候用`*string`,参见[这里](https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html)。简单说,使用 string,在unmarshal时如果字段 missing 则赋值为空字符串,而如果使用`*string`,缺失的字段值为 nil。如果一个字段被 update 的时候可以为空字符串,那么最好设计成`*string`,否则不指定时就会被自动 update 成空字符串。同样,bool 类型如果不指定默认为 false
- 什么时候用 `string` 什么时候用`*string`,参见[这里](https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html)。简单说,使用 string,在unmarshal时如果字段 missing 则赋值为空字符串,而如果使用`*string`,缺失的字段值为 nil。如果一个字段被 update 的时候可以为空字符串,那么最好设计成`*string`,否则不指定时就会被自动 update 成空字符串。同样,bool 类型如果不指定默认为 false。类似的讨论在 gophercloud [也有](https://github.com/gophercloud/gophercloud/issues/1332)。

在 api 的 update 操作中,如果一个字段定义:

`bool,omitempty`,则 client 不能设置 false

`string,omitempty`,则不能设置空字符串

`*bool或*string`,如果没有设置,则发送 null,如果设置 false 或空串,则在 body 中会体现

`*bool,omitempty`,如果没有设置,则发送的 body 体中不包含这个字段

- 字符串拼接除了 Sprintf(返回字符串),还可以使用 `strings.Join([]string{s,"ewrwer"},"")`

Expand All @@ -559,6 +604,29 @@ go func(doneCh chan<- bool) {
fmt.Println(s)
```

- stringint:<https://gobyexample.com/number-parsing>

```go
newPort, err := strconv.Atoi(string)
```

- 实现 Contains 方法

```go
import "sort"
// StringContains searches if a string list contains the given string or not.
func StringContains(list []string, a string) bool {
sort.Strings(list)
index := sort.SearchStrings(list, a)
if index < len(list) && list[index] == a {
return true
}
return false
}
```



### 错误处理

- 博客
Expand Down
30 changes: 30 additions & 0 deletions _posts/生活/2019-02-27-nz-holiday-park-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
layout: post
title: 新西兰的 Holiday Park(一)
category: 生活
description: 新西兰露营体验
---

![](/images/2019-02-27-nz-holiday-park-1/1.jpg)

去年圣诞节期间曾带着全家到新西兰北岛著名的旅游胜地 Taupo 游玩,其实一年之前就去过,但当时孩子还小,基本也没怎么玩。回家之后就觉得这个地方值得多去几次,Taupo 之所以是度假胜地,是因为它不但景色好,还有湖,有温泉,有(小)瀑布,有虾场,有水上运动,不像新西兰别的小镇那样无聊。当然,本文的重点不是为了介绍 Taupo,而是在 Taupo 的露营体验。

在国内的时候从没有体验过露营,感觉露营是玩极限运动的人(比如登山爱好者)才干的事儿,来新西兰后也从未尝试。但在平时跟朋友们聊天过程中得知,新西兰小学可能会有露营的活动,而且据说到5、6年级可能还会在老师的带领下出去露营一个星期。我听了后心里很是焦虑,从没干过这事儿,孩子到时候出去啥也不会弄可怎么混?于是我心里才萌生带孩子出去露营的念头。

说干就干,趁着去年“黑五”期间各种打折,花了不到650刀,把东西都买齐活了,帐篷、睡袋、夜灯、防潮垫、冰桶等,而且恰好再过一个多月是圣诞节,反正中国人也不怎么过圣诞,干脆就订个露营地出去耍。经过一番搜索得知,原来露营还分很多种,相对的就有不同类型的露营地。

- Holiday Parks,此露营地属于商业运营,安全便利、设施齐全。里面除了露营地,还有档次不同的旅馆屋,而露营地也分为带电、不带电的。此外,一般还会有室内和室外娱乐设施,公共厨房、公共卫生间、公共浴室、洗衣间、小商店、游泳池等等,可谓是个小型的生态系统。如果是普通的不带电的帐篷区域,一般是每人每天20-40刀不等。
- 环保部(Department of Conservation)露营地。这种营地一般都在风景区,营地设施通常十分简单且基础,但便宜,部分地方甚至免费,而且通常没有管理人员。里面最多提供简易厕所、自来水、淋浴,有些地方可能还是冷水淋浴。总之,选择这种类型的露营,需要比较齐全的露营设施。
- Freedom Camping,这种比较野蛮,就是走哪睡哪,但要注意不要误闯私人领地。

其实我个人心里把常规露营分为两种:

1、深度露营。不管是开房车还是搭帐篷,吃喝拉撒都自己解决,不依赖于露营地。这种露营要求设施齐全,特别是吃饭的家伙事儿(锅碗瓢盆等)得有。这种露营的目的是为了逃离人类聚集区,一般扎在风景名胜、原始森林或者沙滩边上,周边几公里内没有超市、饭馆啥的。

![](/images/2019-02-27-nz-holiday-park-1/2.jpg)

2、度假式露营。露营地一般在稍大的度假城市周边,出行方便。开私家车,只带帐篷等必备物品,这里强调私家车是因为一家人开着房车在城市里瞎转悠不合适,停车也不方便。吃饭可以选择周边的饭馆或者临时到超市买点菜在露营地的公共厨房做。白天一般不在露营地待,出去耍。

![](/images/2019-02-27-nz-holiday-park-1/3.jpg)

对于我们这种初级露营者,Holiday Park 的 unpowered site 是首选。一方面确实可以体验正儿八经的搭帐篷,另一方面这种营地设施齐全,基本不需要带太多东西,轻装上阵,也就游刃有余。
Binary file added images/2019-02-27-nz-holiday-park-1/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/2019-02-27-nz-holiday-park-1/2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/2019-02-27-nz-holiday-park-1/3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bd188d1

Please sign in to comment.