2013-07-04 42 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