Присвоение числа с плавающей запятой целочисленному элементу структуры - PullRequest
1 голос
/ 12 января 2020

Я прохожу Тур по Go и меня смущает 4/27 (https://tour.golang.org/moretypes/4)

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    p := &v
    p.X = 1e9 // <- this line does not produce a type error
    fmt.Println(v) // {1000000000 2} implicite conversion of int to float?
}

Я ожидал бы этого в JavaScript но не строго типизированный язык. Я, должно быть, упускаю что-то фундаментальное.

Ответы [ 3 ]

3 голосов
/ 12 января 2020

Эта строка:

 p.X = 1e9

Является назначением . Spe c имеет следующее требование для присвоений:

В присваиваниях каждое значение должно быть присваиваемым типу операнда, которому оно назначено ...

И следующее правило присваивания охватывает вышеупомянутое присвоение:

1e9 является нетипизированной константой с плавающей запятой , и значение точно представлено значением типа int , так что все хорошо.

Было бы ошибкой во время компиляции, если бы она была типизированной константой, например,

p.X = float64(1e9)
// error: cannot use float64(1e+09) (type float64) as type int in assignment

Поскольку вышеупомянутое правило присваивания не будет применяться, и ни все другие правила.

То же самое происходит, если нетипизированное значение константы с плавающей запятой не может быть представлено значением типа int, например, в следующих случаях:

p.X = 1e99
// error: constant overflows int

p.X = 1.1
// error: constant 1.1 truncated to integer
2 голосов
/ 12 января 2020

Спецификация языка программирования Go

Константы

Постоянное значение представлено руной, целым, плавающим -точечный, мнимый или строковый литерал, ...

Числовые значения c Константы представляют точные значения произвольной точности и не переполняются.

Константы могут быть напечатаны или нетипизированы. Литеральные константы ... нетипизированы.

Константе может быть задан тип ... неявно при использовании в объявлении переменной .... Ошибка, если значение константы не может быть представлено как значение соответствующий тип.


type Vertex struct {
    X int
    Y int
}

v := Vertex{1, 2}
p := &v
p.X = 1e9 // <- this line does not produce a type error

1e9 - это нетипизированная числовая константа c, выраженная в виде литерала с плавающей запятой.

Когда нетипизированная цифра c константа 1e9 присваивается переменной int (p.X, тип Vertex {X int}), ей дается тип int неявно. 1e9 (1,000,000,000) может быть представлено как значение типа int.

1 голос
/ 12 января 2020

Спецификация / преобразования Go языка программирования :

Преобразование может появляться буквально в источнике или подразумевается контекстом, в котором появляется выражение.

Спецификация языка программирования Go / преобразования между цифрами c типами

При преобразовании числа с плавающей запятой в целое число дробь отбрасывается (усечение до нуля).

Здесь:

p.x = 1e9 // it's floating literal with implied conversion by context

https://golang.org/ref/spec#Conversions

...