跳轉到內容

Io 程式設計

50% developed
來自華夏公益教科書

Io 初學者指南

  1. 關於 Io 和本書
  2. 入門
  3. 您的第一個程式
  4. Io 程式的基本組成部分
  5. 物件

載入項和您

壓縮

加密

網路

伺服器

Io 語言頁面

關於此維基

此作品在 GNU FDL、CC BY SA 和 Io 的許可下分離許可。

本教程的作者是

  • Daniel Ehrenberg (LittleDan)
  • Samuel A. Falvo II
  • Olle Jonsson(關於字串連線的說明)

以及許多希望保持匿名的其他人。

你好世界

在學習程式設計時,通常學習的第一件事是如何編寫一個將“Hello, world!”列印到控制檯的程式。它讓程式設計師瞭解簡單程式的結構。Io 有很多方法可以將內容寫入控制檯,因此有時在使用哪一種方面可能會令人困惑。最常用的方法是 write 函式。輸入 Io 的互動式直譯器(在控制檯中輸入io)並鍵入以下內容

write("Hello, world!\n")

使用互動式直譯器,這應該看起來像

user@computer:~$ io
Io> write("Hello, world!\n")
Hello, world!
==> nil

另一種方法是

"Hello, world!\n" print

其中一些是有道理的。看起來write正在告訴 Io 將某些內容寫入控制檯,特別是它後面的內容。它後面的內容在引號中,所以它是一些文字,它將被列印。但是為什麼那裡有括號,結尾處的\n是什麼,為什麼在引號文字後面有一個箭頭呢?

括號告訴write使用括號內的內容,這被稱為引數write被稱為函式(還記得數學中的函式嗎?)。在括號內可能有多個引數,用逗號隔開,在一個函式中。write的第一個也是唯一的引數,即"Hello, world!\n",是一個字串(因為它是一串字母)。

字串末尾的\n是一個轉義序列。您可以透過它以反斜槓開頭來判斷。此特定轉義序列表示換行符,相當於按回車鍵。如果您在字串中間(或者至少是這種型別的字串——稍後我們會介紹)按下了回車鍵,它會使 Io 混亂。

帶有箭頭和write函式引數的字串的地方是write返回的值。每個函式都會返回值。對於某些函式,返回一些內容是有意義的(例如,用於將兩個數字相加的函式),但對於其他函式,它只是返回使用引數完成的一些簡單內容。在本例中,write返回特殊值nil,表示它沒有要返回的內容。

連線字串

使用雙點運算子連線字串。或者,您可以使用字串插值,如下所示。

假設olle是一個Person例項,它既有名字也有姓氏

Io> olle
==> Object_0080B818 do(
  appendProto(Object_00806B58)
  lastname := "Jonsson"
  title := "Developer"
  firstname := "Olle"
)

我們希望有一個方法可以在名字和姓氏之間新增一個空格來顯示它們

Io> olle fullname := method(firstname .. " " .. lastname)
==> method(firstname ..(" ") ..(lastname))

或者,使用字串插值

Io> olle fullname := method("#{firstname} #{lastname}" interpolate)
==> method("#{firstname} #{lastname}" interpolate)

現在,呼叫olle fullname將產生"Olle Jonsson"。檢視返回的方法物件,我們可以看到 Io 直譯器是如何為..()方法建立常規訊息呼叫的(括號)。

所以,這是新的olle例項

Io> olle
==> Object_0080B818 do(
  appendProto(Object_00806B58)
  fullname := Block_007B5030
  lastname := "Jonsson"
  title := "Developer"
  firstname := "Olle"
)

(注意:只有此例項具有fullname方法。您可以將fullname方法新增到Person中,這將透過olle的原型Person使它對olle可用。此外,firstname、lastname 和 title 也可以移到 Person 中。但這只是示例程式碼片段的方式。)

簡單算術

在 Io 中,您可以使用算術表示式,它們將正常工作。Io 中的算術就像函式一樣,只是它使用物件來幫助。物件使得您不必鍵入類似 +(1, 2) 的內容,而是可以鍵入 1+2。稍後會詳細介紹物件。+ 仍然是一個函式,因此它返回一個值。這非常有用;它使您可以將 Io 用作簡單的計算器。關於它正在做什麼的說明放在兩個斜槓後面(就像這樣://)。

Io> 1+2 //addition
==> 3

Io> 4-5 //subtraction
==> -1

Io> 7*3 //multiplication
==> 21

Io> 3/6 //division
==> 0.50000

Io> 2**3 //exponents
==> 8

Io> 7%2 //remainder of 7/2 (technically, 7 mod 2)
==> 1

這遵循正常的運算順序(稱為優先順序),可以使用括號。正如您所預期的那樣,您可以在數字上使用write,但不會包含換行符。您必須使用write的多引數來列印多個內容,然後它將返回所有這些內容組合在一起。因此,要列印(1/3)**2,您將編寫

write((1/3)**2, "\n")

正如您所預期的那樣,這將列印 0.11111。它返回字串 "0.11111\n",因為使用write函式時,多個引數將轉換為字串並連線在一起。然後該值被列印並返回。

變數

變數基本上是一個代表值的單詞。它們有點像數學中的變數,只是在數學中,變數只能是數字,並且它們只有一個字母長。在程式設計中,函式、物件、字串和數字都是變數型別,但我們還沒有定義任何變數。許多變數,例如 write、3 和 "Hello, world!" 已經可以使用,但其中只有一部分可以更改。您可以使用 = 和 := 建立自己的變數。以下是建立和使用變數的一些示例

x := 3
line := "\n"
write(x, line)

您能說出發生了什麼嗎?變數 x 被設定為 3,變數 line 被設定為 "\n",它等效於換行符。然後,x 和 line 的內容被寫入控制檯。由於 x 是 3 並且 line 是一個換行符,因此這將列印 3 然後轉到控制檯的下一行。該函式返回 "3\n"。

在 Io 中,建立和更改變數的值之間存在差異。如果變數尚不存在,您必須使用 :=,但如果您已經使用 := 為其賦予了初始值,則可以使用 = 用於後續定義。以下是一個示例

x := 1
incrementor := 2
write("x is ", x, "\n")
x = x + incrementor
write("but when we added ", incrementor, " to it, it became ", x, "\n")

有時我們使用 :=,有時我們使用 = 可能令人困惑,但您會習慣的。如果您願意,您可以始終使用 :=,但當我們稍後進入物件時,一直使用 := 會很不方便,因此您應該在適當的時候開始使用 =。

程式

到目前為止,您一直只是在使用 Io 的互動式直譯器。這會阻止您建立更大的應用程式或為他人編寫內容。如果您想編寫要重用的程式碼,只需將其放在一個文字檔案中,並使用io <filename>執行它,其中<filename>是您使用的檔名稱。以下是在 Linux 上使用檔案儲存程式的示例

user@computer:~$ cat > incrementor.io
x := 1
incrementor := 2
writeln("x is ", x)
x = x + incrementor
writeln("but when we added ", incrementor, " to it, it became ", x)
user@computer:~$ io incrementor.io
x is 1
but when we added 2 to it, it became 3
user@computer:~$

這是我們剛剛做的最後一個示例。如果您注意到,我使用了 .io 副檔名。這在任何情況下都不是強制性的,這只是一種約定。如果您注意到,這次發生的事情與我們從檔案中執行時有所不同。與以前不同的是,我們沒有看到每個函式返回的內容。相反,我們只看到了由write顯式輸出的內容。

如果您使用的是 Linux 或類似系統(如 Unix、Mac OS X 或 Cygwin),您可以使其能夠透過鍵入./yourProgram.io(其中 yourProgram.io 是您的程式名稱)來執行,而無需在前面加上io。這可以透過在程式開頭新增一行程式碼,然後賦予其可執行許可權來實現。在 Linux 上,該程式碼為

#! /usr/bin/env io

對於其他系統,它可能會有所不同。要賦予它可執行許可權,只需鍵入以下內容

chmod +x yourProgram.io

同樣,這在不同的系統上可能有所不同。完成此操作後,程式碼的實際執行不會發生任何變化,但您可以例如雙擊 GUI 中的原始碼檔案,它將執行。

編寫函式

正如我之前所說,函式只是另一種型別的變數,因此您可以使用 := 建立它們,並使用 = 更改它們。函式本身是由一個名為method的函式建立的。以下是一個函式示例

add := method(a, b, //function to add 2 numbers
  a + b
)
writeln(add(1, 2)) //writes 3
x := 1
writeln(add(3, x)) //writes 4
x = add(4, 5) //9
writeln(x) //writes 9
x = add(x, 1) //in effect increment x by 1
writeln(x) //writes 10

函式 add 接收兩個引數,a 和 b,然後返回 a + b。如果我們使用變數名 'this' 和 'that' 代替 a 和 b,在 a 和 b 使用的任何地方,它將執行完全相同的事情。在這種情況下,該函式將被寫成

add := method(this, that,
  this + that
)

函式的實際作用是接收一個引數列表,然後將這些引數分配給定義函式時指定的 *區域性變數*。區域性變數只存在於你正在操作的函式中,你無法在函式外部訪問它們。在最近的案例中,這些區域性變數是 'this' 和 'that',因此變數 'this' 將獲取第一個引數,變數 'that' 將獲取第二個引數。然後執行函式的剩餘部分並返回結果。函式可以包含多行程式碼,最後一行將是返回的值。以下是一個示例

examineArgs := method(this, that,
  writeln("This is ", this, ".")
  writeln("That is ", that, ".")
)
// usage:
examineArgs(3, 5)
/* writes:
This is 3.
That is 5. */
x := examineArgs("hi", "bye")
/* writes:
This is hi.
That is bye. */
write(x)
/* writes:
That is bye. */

為什麼 x 被設定為 "That is bye.\n"?因為這是 examineArgs 返回的值。它返回最後一行程式碼的值,即 write("That is ", that, ".\n") 的值。該值被設定為 "bye",因此它列印字串 "That is bye.\n" 並返回相同的字串。

如果你想要在函式結束之前返回某些內容,可以使用 return 函式。與大多數函式不同,你不需要在呼叫 return 函式時在引數周圍加括號。以下是一個使用示例

returning := method(this, that,
  writeln(this)
  return this
  writeln(that)
)
x := returning(1, 2)
//writes "1\n"
write(x) //writes 1 with no newline

如你所見,return 之後的程式碼完全沒有被使用。目前這看起來並沒有什麼用,但稍後在學習到流程控制時,它將被頻繁使用。

條件語句

Io 中的條件語句使用 if 函式建立

if(a == 1) then(
  writeln("a is one")
) else(
  writeln("a is not one")
)

然而,更推薦的寫法是(不需要 then() 和 else() 訊息,因此速度更快)

if(a == 1, writeln("a is one"), writeln("a is not one"))
華夏公益教科書