Reputation: 13525
I define the number to be input by user as var input float64
and I input an integer and I would expect to get an error but I get err = <nil>
. What am I missing?
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)
}
This is the output:
C:\Go\src\play\exercise>go run exercise2.go
Enter a number to take its square root: 1
err = <nil>
n is 1:
Upvotes: 4
Views: 740
Reputation: 193
Scanf scans text read from standard input, storing successive space-separated values into successive arguments as determined by the format. It returns the number of items successfully scanned.
Scanf returns the number of things it read. In this case n == 1 because... you entered one token followed by a newline. Presumably, you want the value of input
, not n
.
Upvotes: 1
Reputation: 166925
The Go Programming Language Specification
Specific rules apply to (non-constant) conversions between numeric types.
Conversions between numeric types
For the conversion of non-constant numeric values, the following rules apply:
- When converting between integer types, if the value is a signed integer, it is sign extended to implicit infinite precision; otherwise it is zero extended. It is then truncated to fit in the result type's size. For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. The conversion always yields a valid value; there is no indication of overflow.
- When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero).
- When converting an integer or floating-point number to a floating-point type, or a complex number to another complex type, the result value is rounded to the precision specified by the destination type. For instance, the value of a variable x of type float32 may be stored using additional precision beyond that of an IEEE-754 32-bit number, but float32(x) represents the result of rounding x's value to 32-bit precision. Similarly, x + 0.1 may use more than 32 bits of precision, but float32(x + 0.1) does not.
In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent.
In Go, you can convert from an integer type to a floating-point type. Therefore, there is no reason not to be forgiving.
In computing, the robustness principle is a general design guideline for software:
Be conservative in what you do, be liberal in what you accept from others (often reworded as "Be conservative in what you send, be liberal in what you accept").
The principle is also known as Postel's law, after Internet pioneer Jon Postel, who wrote in an early specification of the Transmission Control Protocol that:1
TCP implementations should follow a general principle of robustness: be conservative in > what you do, be liberal in what you accept from others.
In other words, code that sends commands or data to other machines (or to other programs on the same machine) should conform completely to the specifications, but code that receives input should accept non-conformant input as long as the meaning is clear.
Upvotes: 3