第八章

走在乡间的小路上, 牧童的歌声在荡漾, 喔喔喔喔他们唱:

(女)太阳啊一出往西落哇, 听我唱唱十八摸, 听我唱唱十八摸哇, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 听我唱唱十八摸哇, 我的小郎吔, 
(男)哎, 叫我干什么?  
(女)我只能给你看来我不能给你摸哇.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活. 

(女)老板那听了十八摸呀, 不花银钱摸不着, 不花银钱摸不着哇, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 不花银钱摸不着呀, 叫声小郎呀,  
(男)哎, 叫我干什么?  
(女)我只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸. 

(女)老年人听了十八摸呀, 浑身上下打哆嗦, 浑身上下打哆嗦呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 浑身上下打哆嗦哎嗨哟, 叫声小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)小伙子听了十呀八摸呀, 晚上回来把老婆来摸, 晚上回来把老婆来摸哇, 哎嗨哎嗨哟, 哎嗨哎嗨哟. 晚上回来把老婆来摸哇, 叫声小郎哎.  
(男)哎, 叫我干什么?  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐头毛上边呀, 一头青丝如墨染, 好比乌云遮满天呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好象乌云遮满天呀, 叫声小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的眉毛上边那, 两道眉毛弯又弯, 好比月牙少半边那, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好比月牙少半边那, 叫声小郎哎,  
(男)哎, 叫我干什么?  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的眼睛上边那, 两个小秋波含在两边呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 两个小秋波含在两边呀, 我的小郎哎.  
(男)哎, 叫我干什么?  
(女)只能给你看来不能给你摸呀.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的鼻子上边呀, 大头朝上小头朝下, 好象一座小金山哟, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好象一座小金山哪, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的耳朵上边那, 两个耳朵象水饺, 还有一对大耳环哪, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 还有一对大耳环哪, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的肩上边呀, 两个小肩圆又圆, 越摸越喜欢呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 越摸越喜欢呀, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的胳膊上边那, 两个胳膊弯又弯, 好象流水变又弯呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好象流水弯又弯呀, 叫声小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的脊梁上边那, 并分麒麟在两边, 越摸越喜欢呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 越摸我越喜欢呀, 叫声小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)我不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的臀上边那, 两个屁股圆又圆, 好象两个大木锨呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好比两个大木锨呀, 叫我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸哇.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的腿上边呀, 两条大腿圆又圆, 我越摸越喜欢哪, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 越摸越喜欢哪, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)我不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的小金连呀, 脚指头好比那小蒜辨, 摸来摸去软如棉呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 摸来摸去软如棉呀, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的咪咪边呀, 两个咪咪圆又圆, 好比那出笼的馒头鲜哪, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好象那出笼的馒头鲜哪, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的奶头边呀, 两个奶头滑溜溜, 好象两个小俘虏呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好比两个小俘虏呀, 我的小郎哎.  
(男)哎, 叫我干什么?  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越快活, 越摸越想摸.  

(女)一摸呀摸到大姐的肚脐边呀, 肚边脐子圆又圆, 比做一个小金钱哪, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 好比一个小金钱哪, 叫声小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(女)一摸呀摸到大姐的沟里边呀, 好象那江湖水连天, 还有一个小金山哪, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 还有大山在里边哪, 我的小郎哎.  
(男)哎, 叫我干什么.  
(女)只能给你看来不能给你摸.  
(男)不摸白不摸, 越摸越想摸, 越摸越快活.  

(合)来来来, 你看日头往西落呀, 你听我唱罢了十八摸, 俺两个上被窝呀, 哎嗨哎嗨哟, 哎嗨哎嗨哟, 俺两个上被窝哇. 

科学的看来, 这个古曲的格式是很规整的. 唱得如诗般使人心神荡漾. 《人月神话》总结的好:Form is liberating. 结构使人解放.

Go, 也来给大爷唱一曲儿.

Go清清嗓子说, 此曲儿共分三段儿, 男女对唱二十片. 每片第一句为主, 后三句重复带少许变化. 第一句的规律也是ABBCCBD. 这就是slice切片啊. 先听两句:

package main
import (
    "fmt"
)
var A = []string{
    "太阳啊一出往西落",
    "老板那听了十八摸",
}
var B = []string{
    "听我唱唱十八摸",
    "不花银钱摸不着",
}
var C = "哎嗨哎嗨哟"
var D = []string{
    "我的小郎",
    "叫声小郎",
}
var E = []string{
    "哇","吔","呀","哎",
}
func main(){
    for i, b := range B {
            fmt.Printf("(女)%s%s,%s,%s%s,%s,%s,%s%s,%s%s,\n",A[i],E[i%4],b,b,E[(i+1)%4],C,C,b,E[(i+2)%4],D[i],E[(i+3)%4])
    }
}

ABDE用[]string声明字串切片并对底层的数组初始化. 注意每行和每个单元是逗号结束的. 这样就不会有分号添进来捣乱. string字串就是引号引起的一串字符. 字串的底层是字节的数组. 数组的意思就是内存里一片连续的相同大小的格子, 字串的每个格子放一个byte字节. 而字串数组的每个格子代表着一个字串, 其实是两个值, 一个是长度, 一个放对应字节数组的地址. 就是下面的意思:

var D = []string{
    "我的小郎",
    "叫声小郎",
}

零号: |一号|    =》D是字串数组的切片
       |长度|
       |容量|    

一号:    |二号|    =》切片底层的字串一
     |长度|        
       |三号| =》切片底层的字串二
       |长度|      

二号: |我|    =》字串一底层的字节数组
       |的|
       |小|
       |郎|        

三号:    |叫|    =》字串二底层的字节数组
       |声|
       |小|
       |郎|        

几号代表的是它们在内存中的位置, 并不一定挨在一起.

零号的地方放的是个切片, 有三个数分别代表它的内容所在的位置(一号), 其长度(2), 和容量(2).

一号的地方放的是零号位置的切片的内容, 两个单元紧挨着, 每个单元有两个数分别代表着其内容所在的位置(二号三号)和其长度(都是12)

二号的地方放的是一号位置的第一个单元的内容, 是紧挨着的12个字节单元. 虽然我画的是4个汉字的单元, Go天生UTF8, 每个汉字要占3个字节.

二号的地方放的是一号位置的第二个单元的内容. 刚好也是12个字节但内容不同.

所以, 可以很清楚的看到, 切片和字串的底层都是数组. 字串只能代表字节数组, 切片则无此限制. 但就算是某个切片代表着字节数组, 并且其内容和某个字串代表的字节数组相同, 它们也不是同一胎型. 原因有二. 一是其对应字节数组的内存位置不同, 也就是地址不同的意思. 二是, 字串是固定的, 切片是可变的. 就是说, 你不可以改变字串的内容和长度, 但切片的可以. 只有切片的容量, 也就是它对应的数组所占的地皮的大小, 是不可以改变的.

除此之外, 几个切片可以代表同一地址的数组, 这样, 只要通过一个切片改动数组的内容, 也就是改了其它切片的内容. 这在func时是非常有用的.

切片和字串的单元号也称index下标, 从0开始到长度减一, 如A[0],D[i]等.

另外, 上面的%是mod取模操作, 保证下标不越界. 每个数组就像军营, 越界立马被枪杀, 导致运行panic.