、數(shù)組
目前創(chuàng)新互聯(lián)已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、井岡山網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
與其他大多數(shù)語(yǔ)言類似,Go語(yǔ)言的數(shù)組也是一個(gè)元素類型相同的定長(zhǎng)的序列。
(1)數(shù)組的創(chuàng)建。
數(shù)組有3種創(chuàng)建方式:[length]Type 、[N]Type{value1, value2, ... , valueN}、[...]Type{value1, value2, ... , valueN} 如下:
復(fù)制代碼代碼如下:
func test5() {
var iarray1 [5]int32
var iarray2 [5]int32 = [5]int32{1, 2, 3, 4, 5}
iarray3 := [5]int32{1, 2, 3, 4, 5}
iarray4 := [5]int32{6, 7, 8, 9, 10}
iarray5 := [...]int32{11, 12, 13, 14, 15}
iarray6 := [4][4]int32{{1}, {1, 2}, {1, 2, 3}}
fmt.Println(iarray1)
fmt.Println(iarray2)
fmt.Println(iarray3)
fmt.Println(iarray4)
fmt.Println(iarray5)
fmt.Println(iarray6)
}
結(jié)果:
[0 0 0 0 0]
[1 2 3 4 5]
[1 2 3 4 5]
[6 7 8 9 10]
[11 12 13 14 15]
[[1 0 0 0] [1 2 0 0] [1 2 3 0] [0 0 0 0]]
我們看數(shù)組 iarray1,只聲明,并未賦值,Go語(yǔ)言幫我們自動(dòng)賦值為0。再看 iarray2 和 iarray3 ,我們可以看到,Go語(yǔ)言的聲明,可以表明類型,也可以不表明類型,var iarray3 = [5]int32{1, 2, 3, 4, 5} 也是完全沒問題的。
(2)數(shù)組的容量和長(zhǎng)度是一樣的。cap() 函數(shù)和 len() 函數(shù)均輸出數(shù)組的容量(即長(zhǎng)度)。如:
復(fù)制代碼代碼如下:
func test6() {
iarray4 := [5]int32{6, 7, 8, 9, 10}
fmt.Println(len(iarray4))
fmt.Println(cap(iarray4))
}
輸出都是5。
(3)使用:
復(fù)制代碼代碼如下:
func test7() {
iarray7 := [5]string{"aaa", `bb`, "可以啦", "叫我說(shuō)什么好", "()"}
fmt.Println(iarray7)
for i := range iarray7 {
fmt.Println(iarray7[i])
}
}
二、切片
Go語(yǔ)言中,切片是長(zhǎng)度可變、容量固定的相同的元素序列。Go語(yǔ)言的切片本質(zhì)是一個(gè)數(shù)組。容量固定是因?yàn)閿?shù)組的長(zhǎng)度是固定的,切片的容量即隱藏?cái)?shù)組的長(zhǎng)度。長(zhǎng)度可變指的是在數(shù)組長(zhǎng)度的范圍內(nèi)可變。
(1)切片的創(chuàng)建。
切片的創(chuàng)建有4種方式:
1)make ( []Type ,length, capacity )
2) make ( []Type, length)
3) []Type{}
4) []Type{value1 , value2 , ... , valueN }
從3)、4)可見,創(chuàng)建切片跟創(chuàng)建數(shù)組唯一的區(qū)別在于 Type 前的“ [] ”中是否有數(shù)字,為空,則代表切片,否則則代表數(shù)組。因?yàn)榍衅情L(zhǎng)度可變的。如下是創(chuàng)建切片的示例:
復(fù)制代碼代碼如下:
func test8() {
slice1 := make([]int32, 5, 8)
slice2 := make([]int32, 9)
slice3 := []int32{}
slice4 := []int32{1, 2, 3, 4, 5}
fmt.Println(slice1)
fmt.Println(slice2)
fmt.Println(slice3)
fmt.Println(slice4)
}
輸出為:
[0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[]
[1 2 3 4 5]
如上,創(chuàng)造了4個(gè)切片,3個(gè)空切片,一個(gè)有值的切片。
(2)切片與隱藏?cái)?shù)組:
一個(gè)切片是一個(gè)隱藏?cái)?shù)組的引用,并且對(duì)于該切片的切片也引用同一個(gè)數(shù)組。如下示例,創(chuàng)建了一個(gè)切片slice0,并根據(jù)這個(gè)切片創(chuàng)建了2個(gè)切片 slice1 和 slice2:
復(fù)制代碼代碼如下:
func test9() {
slice0 := []string{"a", "b", "c", "d", "e"}
slice1 := slice0[2 : len(slice0)-1]
slice2 := slice0[:3]
fmt.Println(slice0, slice1, slice2)
slice2[2] = "8"
fmt.Println(slice0, slice1, slice2)
}
輸出為:
[a b c d e] [c d] [a b c]
[a b 8 d e] [8 d] [a b 8]
可見,切片slice0 、 slice1 和 slice2是同一個(gè)底層數(shù)組的引用,所以slice2改變了,其他兩個(gè)都會(huì)變。
(3)遍歷、修改切片:
復(fù)制代碼代碼如下:
func test10() {
slice0 := []string{"a", "b", "c", "d", "e"}
fmt.Println("\n~~~~~~元素遍歷~~~~~~")
for _, ele := range slice0 {
fmt.Print(ele, " ")
ele = "7"
}
fmt.Println("\n~~~~~~索引遍歷~~~~~~")
for index := range slice0 {
fmt.Print(slice0[index], " ")
}
fmt.Println("\n~~~~~~元素索引共同使用~~~~~~")
for index, ele := range slice0 {
fmt.Print(ele, slice0[index], " ")
}
fmt.Println("\n~~~~~~修改~~~~~~")
for index := range slice0 {
slice0[index] = "9"
}
fmt.Println(slice0)
}
如上,前三種循環(huán)使用了不同的for range循環(huán),當(dāng)for后面,range前面有2個(gè)元素時(shí),第一個(gè)元素代表索引,第二個(gè)元素代表元素值,使用 “_” 則表示忽略,因?yàn)間o語(yǔ)言中,未使用的值會(huì)導(dǎo)致編譯錯(cuò)誤。
只有一個(gè)元素時(shí),該元素代表索引。
只有用索引才能修改元素。如在第一個(gè)遍歷中,賦值ele為7,結(jié)果沒有作用。因?yàn)樵谠乇闅v中,ele是值傳遞,ele是該切片元素的副本,修改它不會(huì)影響原本值,而在第四個(gè)遍歷——索引遍歷中,修改的是該切片元素引用的值,所以可以修改。
結(jié)果為:
~~~~~~元素遍歷~~~~~~
a b c d e
~~~~~~索引遍歷~~~~~~
a b c d e
~~~~~~元素索引共同使用~~~~~~
aa bb cc dd ee
~~~~~~修改~~~~~~
[9 9 9 9 9]
(4)、追加、復(fù)制切片:
復(fù)制代碼代碼如下:
func test11() {
slice := []int32{}
fmt.Printf("slice的長(zhǎng)度為:%d,slice為:%v\n", len(slice), slice)
slice = append(slice, 12, 11, 10, 9)
fmt.Printf("追加后,slice的長(zhǎng)度為:%d,slice為:%v\n", len(slice), slice)
slicecp := make([]int32, (len(slice)))
fmt.Printf("slicecp的長(zhǎng)度為:%d,slicecp為:%v\n", len(slicecp), slicecp)
copy(slicecp, slice)
fmt.Printf("復(fù)制賦值后,slicecp的長(zhǎng)度為:%d,slicecp為:%v\n", len(slicecp), slicecp)
}
追加、復(fù)制切片,用的是內(nèi)置函數(shù)append和copy,copy函數(shù)返回的是最后所復(fù)制的元素的數(shù)量。
(5)、內(nèi)置函數(shù)append
內(nèi)置函數(shù)append可以向一個(gè)切片后追加一個(gè)或多個(gè)同類型的其他值。如果追加的元素?cái)?shù)量超過了原切片容量,那么最后返回的是一個(gè)全新數(shù)組中的全新切片。如果沒有超過,那么最后返回的是原數(shù)組中的全新切片。無(wú)論如何,append對(duì)原切片無(wú)任何影響。如下示例:
復(fù)制代碼代碼如下:
func test12() {
slice := []int32{1, 2, 3, 4, 5, 6}
slice2 := slice[:2]
_ = append(slice2, 50, 60, 70, 80, 90)
fmt.Printf("slice為:%v\n", slice)
fmt.Printf("操作的切片:%v\n", slice2)
_ = append(slice2, 50, 60)
fmt.Printf("slice為:%v\n", slice)
fmt.Printf("操作的切片:%v\n", slice2)
}
如上,append方法用了2次,結(jié)果返回的結(jié)果完全不同,原因是第二次append方法追加的元素?cái)?shù)量沒有超過 slice 的容量。而無(wú)論怎樣,原切片slice2都無(wú)影響。結(jié)果:
slice為:[1 2 3 4 5 6]
操作的切片:[1 2]
slice為:[1 2 50 60 5 6]
操作的切片:[1 2]
本文介紹一些Go語(yǔ)言的基礎(chǔ)語(yǔ)法。
先來(lái)看一個(gè)簡(jiǎn)單的go語(yǔ)言代碼:
go語(yǔ)言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來(lái)進(jìn)一步介紹go的基礎(chǔ)語(yǔ)法。
go語(yǔ)言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問中的fmt包。
log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來(lái)介紹一下go的數(shù)據(jù)類型
下表列出了go語(yǔ)言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。
常量是在程序編譯時(shí)就確定下來(lái)的值,程序運(yùn)行時(shí)無(wú)法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語(yǔ)言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。
算術(shù)運(yùn)算符:
關(guān)系運(yùn)算符:
邏輯運(yùn)算符:
位運(yùn)算符:
賦值運(yùn)算符:
指針相關(guān)運(yùn)算符:
下面介紹一下go語(yǔ)言中的if語(yǔ)句和switch語(yǔ)句。另外還有一種控制語(yǔ)句叫select語(yǔ)句,通常與通道聯(lián)用,這里不做介紹。
if語(yǔ)法格式如下:
if ... else :
else if:
示例代碼:
語(yǔ)法格式:
另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語(yǔ)句,不管下一條case語(yǔ)句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語(yǔ)句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過標(biāo)記退出循環(huán):
--THE END--
參考方法就是先把文件讀出來(lái),把不要的數(shù)組元素刪了后再寫回去;
參考代碼如下:
// std::string jsonPath // json文件路徑
Json::Reader reader;
Json::Value root;
ifstream is;
is.open (jsonPath.c_str(), std::ios::binary );
if (reader.parse(is, root))
{
std::string code;
Json::Value value;
int size = root.size();
for (int i = 0; i size; i++)
{
if(條件)
{
value[i] = root[i];
}
}
is.close();
Json::FastWriter writer;
std::string json_append_file = writer.write(value);
std::ofstream ofs;
ofs.open(jsonPath.c_str());
ofs json_append_file;
ofs.close();
}
需要寫一個(gè)方法,把json數(shù)據(jù)轉(zhuǎn)換成list集合數(shù)據(jù)
public static List jsonToBean(String data, Object bean) {
List list = new ArrayList();
try {
JSONArray array;
try {
array = new JSONArray(data);
for (int i = 0; i array.length(); i++) {
Object toBean = getBean(bean);
JSONObject ob = new JSONObject();
ob = (JSONObject) array.get(i);
toBean = jsonStrToBean(ob, toBean);
list.add(toBean);
}
return list;
} catch (JSONException e) {
try {
Object obj = null;
JSONObject jsonObj = new JSONObject(data);
Object toBean = getBean(bean);
toBean = jsonStrToBean(jsonObj, toBean);
list.add(toBean);
return list;
} catch (JSONException e1) {
log.error("Error covert String to JSONObject", e);
e1.printStackTrace();
}
e.printStackTrace();
log.error("Error covert String to JSONArray", e);
}
} catch (SecurityException e) {
e.printStackTrace();
}
return list;
}
下邊是slice的申明和使用其實(shí)這就是一種動(dòng)態(tài)的數(shù)組復(fù)制代碼 代碼如下:package main
import "fmt"func main() {d := []int{1, 2, 3} //申明一個(gè)slice這個(gè)是動(dòng)態(tài)的數(shù)組,沒有長(zhǎng)fmt.Println(d)
var q, w []intq = d[0:1] //可以定取得上邊的長(zhǎng)度w = d[1:3]d = append(d, 2) //向其中添加元素fmt.Println(d)fmt.Printlnw。
Go語(yǔ)言是谷歌2009年發(fā)布的第二款開源編程語(yǔ)言。Go語(yǔ)言專門針對(duì)多處理器系統(tǒng)應(yīng)用程序的編程進(jìn)行了優(yōu)化,使用Go編譯的程序可以媲美C或C++代碼的速度,而且更加安全、支持并行進(jìn)程。北京時(shí)間2010年1月10日,Go語(yǔ)言摘得了TIOBE公布的2009年年度大獎(jiǎng)。
在谷歌公開發(fā)布的所有網(wǎng)絡(luò)應(yīng)用中,均沒有使用Go,但是谷歌已經(jīng)使用該語(yǔ)言開發(fā)了幾個(gè)內(nèi)部項(xiàng)目。派克表示,Go是否會(huì)對(duì)谷歌即將推出的Chrome OS產(chǎn)生影響,還言之尚早,不過Go的確可以和Native Client配合使用。他表示“Go可以讓應(yīng)用完美的運(yùn)行在瀏覽器內(nèi)?!崩?,使用Go可以更高效的實(shí)現(xiàn)Wave,無(wú)論是在前端還是后臺(tái)。
Go 同時(shí)具有兩種編譯器,一種是建立在GCC基礎(chǔ)上的Gccgo,另外一種是分別針對(duì)64位x64和32位x86計(jì)算機(jī)的一套編譯器(6g和8g)。谷歌目前正在研發(fā)其對(duì)ARM芯片和Android設(shè)備的支持。
Google對(duì)Go寄予厚望。其設(shè)計(jì)是讓軟件充分發(fā)揮多核心處理器同步多工的優(yōu)點(diǎn),并可解決面向?qū)ο蟪绦蛟O(shè)計(jì)的麻煩。它具有現(xiàn)代的程序語(yǔ)言特色,如垃圾回收,幫助程序設(shè)計(jì)師處理瑣碎但重要的內(nèi)存管理問題。Go的速度也非常快,幾乎和C或C++程序一樣快,且能夠快速制作程序。
按值傳遞函數(shù)參數(shù),是拷貝參數(shù)的實(shí)際值到函數(shù)的形式參數(shù)的方法調(diào)用。在這種情況下,參數(shù)在函數(shù)內(nèi)變化對(duì)參數(shù)不會(huì)有影響。
默認(rèn)情況下,Go編程語(yǔ)言使用調(diào)用通過值的方法來(lái)傳遞參數(shù)。在一般情況下,這意味著,在函數(shù)內(nèi)碼不能改變用來(lái)調(diào)用所述函數(shù)的參數(shù)??紤]函數(shù)swap()的定義如下。
代碼如下:
/* function definition to swap the values */
func swap(int x, int y) int {
var temp int
temp = x /* save the value of x */
x = y /* put y into x */
y = temp /* put temp into y */
return temp;
}
現(xiàn)在,讓我們通過使實(shí)際值作為在以下示例調(diào)用函數(shù)swap():
代碼如下:
package main
import "fmt"
func main() {
/* local variable definition */
var a int = 100
var b int = 200
fmt.Printf("Before swap, value of a : %d\n", a )
fmt.Printf("Before swap, value of b : %d\n", b )
/* calling a function to swap the values */
swap(a, b)
fmt.Printf("After swap, value of a : %d\n", a )
fmt.Printf("After swap, value of b : %d\n", b )
}
func swap(x, y int) int {
var temp int
temp = x /* save the value of x */
x = y /* put y into x */
y = temp /* put temp into y */
return temp;
}
讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200
這表明,參數(shù)值沒有被改變,雖然它們已經(jīng)在函數(shù)內(nèi)部改變。
通過傳遞函數(shù)參數(shù),即是拷貝參數(shù)的地址到形式參數(shù)的參考方法調(diào)用。在函數(shù)內(nèi)部,地址是訪問調(diào)用中使用的實(shí)際參數(shù)。這意味著,對(duì)參數(shù)的更改會(huì)影響傳遞的參數(shù)。
要通過引用傳遞的值,參數(shù)的指針被傳遞給函數(shù)就像任何其他的值。所以,相應(yīng)的,需要聲明函數(shù)的參數(shù)為指針類型如下面的函數(shù)swap(),它的交換兩個(gè)整型變量的值指向它的參數(shù)。
代碼如下:
/* function definition to swap the values */
func swap(x *int, y *int) {
var temp int
temp = *x /* save the value at address x */
*x = *y /* put y into x */
*y = temp /* put temp into y */
}
現(xiàn)在,讓我們調(diào)用函數(shù)swap()通過引用作為在下面的示例中傳遞數(shù)值:
代碼如下:
package main
import "fmt"
func main() {
/* local variable definition */
var a int = 100
var b int= 200
fmt.Printf("Before swap, value of a : %d\n", a )
fmt.Printf("Before swap, value of b : %d\n", b )
/* calling a function to swap the values.
* a indicates pointer to a ie. address of variable a and
* b indicates pointer to b ie. address of variable b.
*/
swap(a, b)
fmt.Printf("After swap, value of a : %d\n", a )
fmt.Printf("After swap, value of b : %d\n", b )
}
func swap(x *int, y *int) {
var temp int
temp = *x /* save the value at address x */
*x = *y /* put y into x */
*y = temp /* put temp into y */
}
讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :200
After swap, value of b :100
這表明變化的功能以及不同于通過值調(diào)用的外部體現(xiàn)的改變不能反映函數(shù)之外。