2013-07-04 41 views
4

我將用戶輸入的數字定義爲var input float64,我輸入一個整數,我希望得到一個錯誤,但我得到err = <nil>。我錯過了什麼?爲什麼沒有類型不匹配錯誤?

package main 

import (
    "fmt" 
) 

func main() { 
    var input float64 

    fmt.Print("Enter a number:") 

    n, err := fmt.Scanf("%f\n", &input) 

    fmt.Printf("err = %v\n", err) 

    if err != nil { 
     fmt.Printf("%v is not a float - exiting with error\n", input, err) 
     return 
    } 

    fmt.Printf("n is %v:", n) 
} 

這是輸出:

C:\Go\src\play\exercise>go run exercise2.go 
Enter a number to take its square root: 1 
err = <nil> 
n is 1: 
+2

你知道1是一個完全有效的浮點數嗎? – fuz

+1

不,我不知道。我認爲浮點數需要用小數寫出。按照我的想法,'1.0'不應該給出錯誤,而應該是'1'。例如,在Mark Summerfield關於Go的書中,「浮點數用小數點寫成......」 – Zeynel

+0

我認爲@FUZxxl試圖說的是「1」可以完美地表示爲浮點數,即'1.0'。 '%f'格式應該讀取包含小數點的浮點數。這可能是一個方便的事情,因爲如果所有的需求都是「1」,人們可能不想輸入「1.0」,但是我會對包含實際證據的更完整的答案感興趣;) – fresskoma

回答

3

在GO編程語言規範

Conversions

具體規則適用於數字 類型之間(非恆定)的轉換。數值類型

對於非恆定數值的轉換之間

換算,以下規則 適用:

  1. 當整數類型之間的轉換,如果該值是一個帶符號的 整數,它將符號擴展爲隱式無限精度; 否則爲零擴展。然後將其截尾以適應 結果類型的大小。例如,如果v:= uint16(0x10F0),則 uint32(int8(v))== 0xFFFFFFF0。轉換始終會生成有效的 值;沒有溢出的跡象。
  2. 將浮點數轉換爲整數時,會丟棄部分 (截斷爲零)。
  3. 將整數或浮點數轉換爲浮點型 或將複數轉換爲另一個複雜類型 時,結果值四捨五入爲由目標類型 指定的精度。例如,類型爲 float32的變量x的值可以使用超出IEEE-754 32位數字的附加精度來存儲,但是float32(x)表示 將x的值舍入爲32位精度的結果。同樣,x + 0.1可能會使用多於32位精度的 ,但float32(x + 0.1)不會。

在涉及浮點或複雜 值,如果結果類型不能代表轉換 成功的值,但結果值是依賴於實現的所有非恆定的轉換。

在Go中,您可以從整數類型轉換爲浮點類型。因此,沒有理由不寬容。

Robustness principle

在計算中,穩健性原則,是一個普遍的設計指導 軟件:

在你做什麼保守的,在你從別人 接受什麼樣的自由主義(通常改寫爲「在你發送的內容中保守,在你接受的內容中是自由主義的」 )。

原則也被稱爲Postel的法律,互聯網先驅 喬恩·波斯特爾,誰在傳輸 控制協議的早期規範寫道之後:1

TCP實現應該遵循穩健性的一般原則:是保守在你做什麼,在你自己接受別人的東西時是自由的。接收輸入

換句話說,代碼發送命令或數據的其它機器(或 在同一臺機器上的其他程序)應該完全符合 規格,但代碼應該接受 不符合的輸入,只要因爲意思很清楚。

+1

並且只是爲了完整性,來自golang規範:http://golang.org/ref/spec#Floating-point_literals – pkuderov

+1

這實際上並沒有回答這個問題 – ispilledthejava

1

SCANF掃描文本讀取標準輸入,存儲連續空間分隔值成連續的參數如由格式決定。 它返回成功掃描的項目數。

Scanf返回它讀取的東西的數量。在這種情況下n == 1,因爲...您輸入了一個標記後跟一個換行符。據推測,你想要input的價值,而不是n