Pike学习笔记
?
Pike的安裝(Ubuntu環(huán)境)?
?
pike的語法非常像C++,但是它也是腳本語言,所以具有一般腳本語言的特性。一個簡單的pike程序,hello world:
1 int main() 2 { 3 write("Hello world!\n"); 4 return 0; 5 }? string的用法,及命令行參數(shù)的例子:
#! /usr/local/bin/pike //下次直接打文件名就可以了 int main(int argc, array(string) argv) {write("Welcome to the Very Simple WWW Browser!\n");string url;if(argc == 2)url = argv[1]; //命令行參數(shù)else{write("Type the address of the web page:\n");url = Stdio.stdin->gets(); //從標(biāo)準(zhǔn)輸入中讀取一行字符串 }write("URL: " + url + "\n");return 0; }? 再看看下面段小代碼,會覺得更加熟悉:
1 do 2 { 3 write("Type the address of the web page:\n"); 4 url = Stdio.stdin->gets(); 5 } while(sizeof(url) == 0); //簡直和C++無差
不過map就不是C++中的map了,而是一個用于簡單地代替for的函數(shù),類似于python中的map。
1 void write_one(int x) 2 { 3 write("Number: " + x + "\n"); 4 } 5 int main() 6 { 7 array(int) all_of_them = ({ 1, 5, -1, 17, 17 }); 8 map(all_of_them, write_one); 9 return 0; 10 } 11 12 輸出: 13 Number: 1 14 Number: 5 15 Number: -1 16 Number: 17 17 Number: 17?
值得注意的是,0在pike中代表NULL,None,也代表int 0。所有沒有初始化的變量都將被置為0,這點需要特別注意。當(dāng)然,也可以將只聲明,未初始化的變量看成是一個值未確定的變量。
1 string accumulate_answer() 2 { 3 string result; 4 // Probably some code here 5 result += "Hi!\n"; 6 // More code goes here 7 return result; 8 } 9 10 輸出: 11 0Hi!可以看到,H前面的0并不是我們需要的。
?
pike的內(nèi)置類型有:int, ?float, ?string ?,mapping ?,multiset ?,array (數(shù)組) ,mixed (表任意類型) 。
有點奇怪的是,在聲明變量時還可以使變量是某幾種數(shù)據(jù)類型,比如聲明:
int|string|float x表示的是,x可以是這3種類型中的一種,但不允許是其他的類型。此時不用mixed的原因是,解釋器會對x作參數(shù)類型的檢查。
?
普通變量的賦值通常是a1=a2,但是array的賦值就不能這樣了,這倒是和python的list的賦值一樣,其實是一個引用,而不是一份拷貝。
正確的做法是:
a2 = copy_value(a1);另一種是:
a2 = a1 + ({ });? 這種復(fù)制是遞歸式的,連array內(nèi)的任何數(shù)據(jù)都能copy到一份獨立的出來。
其實只有這三種情況下,賦值才是真的作拷貝工作,那就是:
- int
- float
- string
其他大部分情況都是以引用的方式來解決的。
?
?
類的定義也很有不同,首先是構(gòu)造函數(shù),是以create為函數(shù)名的,且最多只能有一個構(gòu)造函數(shù),當(dāng)然,也可以沒有構(gòu)造函數(shù)。
成員函數(shù)中不允許有同名函數(shù)的出現(xiàn),即不能以參數(shù)的個數(shù)或類型來區(qū)別方法,比如只能有一個稱為eat的函數(shù)存在。
析構(gòu)函數(shù)也是可以存在的,必須稱為destroy。destroy比較少用,因為pike是自帶垃圾回收的,所以析不析構(gòu)意義不大。
很不幸,pike中并沒有如struct關(guān)鍵字,而僅有class。用class同樣也能代替struct的,只要不在class中定義方法即可。
1 class animal 2 { 3 string name; 4 float weight; 5 6 void create(string n, float w) 7 { 8 name = n; 9 weight = w; 10 } 11 12 void eat(string food) 13 { 14 write(name + " eats some " + food + ".\n"); 15 weight += 0.5; 16 } 17 }?
繼承 - - 關(guān)鍵字inherit的用法:
1 class hamster 2 { 3 inherit friend; 4 void dance() 5 { 6 write(name + " dances.\n"); 7 } 8 }?
?
在pike中,一個文件其實就是一個類class,全局變量就是類的成員變量,而函數(shù)就是成員函數(shù)。可以想想成pike解釋器自動為每個文件加上了class{}的符號。
導(dǎo)入一個類(即文件)也是很方便的,只需要在函數(shù)外引入這句:
constant animal = (program)"animal.pike";其中constant是常量的類型,(program)也可以稱為class, 雙引號中的內(nèi)容是文件名。這樣子,類名就暫時為constant常量animal,其他的操作就很操作class對象一樣了。
?
pike創(chuàng)建類對象和C++有些不同,還有調(diào)用方面,一直是用 -> 符號來取成員變量的。假設(shè)fish繼承了animal類,看如下代碼:
1 animal w = fish("Willy", 4000.0); 2 w->eat("tourists"); 3 w->swim();此代碼段中創(chuàng)建的是一個fish對象,而指針是基類animal類型的,那么成員函數(shù)eat會優(yōu)先調(diào)用fish類中的eat,如果沒有定義的話,才調(diào)用animal中的eat。如果要調(diào)用父類中的成員函數(shù),可以使用::符號來索引出父類,類似于C++中的 "super->" 。
pike稱其為dynamic?binding,即指針時刻會依賴于具體的對象是什么,而不是僅僅看指針是什么。
注意animal中并沒有定義swim,那如果是這樣的代碼呢:
1 fish f=animal("willy", 300.0); 2 f->eat("bug"); 3 f->swim();這里創(chuàng)建的是一個animal,而指針卻是派生類的fish指針。雖然這樣寫前兩行并沒有錯,但在第三行會出錯,因為animal中并沒有找到這個函數(shù)。
?
更新奇的用法:
1 inherit Stdio.File; 2 read(); //這是Stdio.File中的一個函數(shù)因為一個文件就是一個類,而inherit可以用于繼承其他類,然后就能直接調(diào)用父類的函數(shù)了。不過一般不推薦這么作,其實可以創(chuàng)建一個類對象,再調(diào)用其中的函數(shù),像這樣:
1 Stdio.File the_file; 2 the_file->read();?
類中的關(guān)鍵字:
1 public //同C++,在pike中是默認(rèn)的 2 3 private //同C++ 4 5 static //不同與C++。類似于C++中的protected,能讓子類訪問。 6 7 local //暫沒有理解其真實用處 8 9 final //禁止子類重定義同樣的函數(shù)名?
整型 int 默認(rèn)為10進(jìn)制,理論上支持無限大的數(shù),且保證精確。有幾種進(jìn)制也很重要:
1 1 十進(jìn)制: 5 2 2 二進(jìn)制: 0b101 3 3 八進(jìn)制: 05 4 4 十六進(jìn)制: 0x5? int也有幾個常用的操作方法:
1 intp(int x) 判斷x是否為int,返回值為0或1 2 random(int limit) 產(chǎn)生一個[0, limit)的隨機(jī)整數(shù) 3 reverse(int x) 將x的二進(jìn)制按位取反?
浮點型 float 的功能就很有限,支持的精度也比較小,超出的部分自動就被裁剪了,具體怎樣裁剪未知。以下有3個比較常用的方法:
1 floatp(float x) 判斷是否是一個浮點數(shù) 2 floor(float x) 去除x的小數(shù)部分,并返回該浮點型 3 ceil(float x) 向上取整,同樣返回的是浮點數(shù)?
pike的內(nèi)置容器有array,mapping,multiset 。array也是支持切片操作的:
1 ({ 1, 7, 3, 3, 7 })[ 1..3 ]?相當(dāng)于?({ 7, 3, 3 }).? array的 == 操作判斷的是是否為同一個array,而不是判斷是否內(nèi)容相等。同理!=符號。
1 array(int) a = ({ 7, 1 }); 2 a==a 3 true //他們相同 4 5 ({ 7, 1 }) == ({ 7, 1 }) 6 false //不相同,但相等? 同時,array也有一些常用的操作:
1 equal(({7,1}), ({7,1})); 判斷兩個array是否相等 2 3 ({ 7, 1, 1 }) + ({ 1, 3 }) 結(jié)果為 ({ 7, 1, 1, 1, 3 }). 求并集操作 4 5 ({ 7, 1 }) | ({ 3, 1 }) 結(jié)果為 ({ 7, 3, 1 }). 合并且去重,每個元素的存在個數(shù)等于之前某一方數(shù)量最多的個數(shù) 6 7 ({ 7, 1 }) & ({ 3, 1 }) 結(jié)果為 ({ 1 }). 求交集操作 8 9 ({ 7, 1 }) - ({ 3, 1 }) 結(jié)果為 ({ 7 }). 求差集操作,左邊存在的,而右邊不存在的 10 11 ({ 7, 1 }) ^ ({ 3, 1 })?結(jié)果為?({ 7, 3 }). 求異或集操作 12 13 ({ 7, 1, 2, 3, 4, 1, 2, 1, 2, 77 }) / ({ 1, 2 })?結(jié)果為?({ ({ 7 }), ({ 3, 4 }), ({ }), ({ 77 }) }). 求切分操作,就是出現(xiàn)一個({1,2})的話就會出現(xiàn)多一個子數(shù)組。 14 15 ({ 7, 1, 2, 3, 4, 1, 2 }) / 3?結(jié)果為?({ ({ 7, 1, 2 }), ({ 3, 4, 1 }) }). 求切分操作,將array按照每3個為一個新的array來創(chuàng)建一個二重數(shù)組,最后如果不足3個就被忽略掉了。 16 17 ({ 7, 1, 2, 3, 4, 1, 2 }) % 3?結(jié)果為?({ 2 }). 就是上一種切分方法所不足3個的,都給裝到一塊,所以數(shù)量不會超過3的 18 19 sizeof(array) 求數(shù)組中的元素個數(shù) 20 21 allocate(size) 一次性創(chuàng)建size個值為0的array 22 23 reverse(array) 反轉(zhuǎn)數(shù)組 24 25 search(haystack, needle) 在haystack中找到第一個出現(xiàn)needle的元素并返回其下標(biāo) 26 27 has_value(haystack,?needle) 判斷在haystack中誰否有元素needle的存在 28 29 replace(array,?old,?new) 將數(shù)組中所有的值為old的元素替換為new?
轉(zhuǎn)載于:https://www.cnblogs.com/xcw0754/p/5066133.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
- 上一篇: 性能测试培训:定位jvm耗时函数
- 下一篇: 前后台传值乱码问题解决