2016-06-09 4 views
2

У меня есть такой код:Могу ли я сделать переопределение типов более оптимальным?

type Speed float64 
type Distance float64 
type Time float64 


func speed(a Distance, b Time) Speed { 
    return Speed(float64(a)/float64(b)) 
} 

func main() { 
    s := Distance(123.0) 
    t := Time(300) 
    fmt.Println(speed(s, t)) 
} 

Могу ли я сделать его более оптимальным путем удаления каким-то образом приведение к float64 в функции скорости?

+1

Нет, но, но что-то вроде этого, я не думаю, что есть веские основания, чтобы не просто использовать float64, если вы не определения каких-либо методов , – JimB

+2

Причина (для меня) проста: я хочу убедиться, что мы работаем на правильном типе, и complier спасет меня от написания множества спецификаций. –

+0

Это _is_ оптимально. – Volker

ответ

2

Нет, вы не можете избежать отбрасывания своего расстояния и времени обратно в поплавки, поскольку для этих типов разделение не определено. И, как было сказано ранее, Go строго типизирован.

Итак, в вашем случае вам придется прикладывать броски повсюду (не очень хорошая идея). Тип aliasing хорош, если вы хотите писать собственные методы для своих типов, но его цель заключается не только в скрытии базового типа под пользовательским.

Однако не все типы работают таким образом. Если вы сделаете псевдоним карты, вы можете без проблем вызвать операторы скобок.

type Map map[string]string 

func main() { 
    m := Map(make(map[string]string)) 
    m["answer"] = "42" 
    fmt.Printf("m's type is %T and answer is %s\n", m, m["answer"]) 
    // 
    // m's type is main.Map and answer is 42 
} 

Кроме того, при инициализации пользовательских псевдонимов, литье ненужно:

type Speed float64 
type Distance float64 

func main() { 
    var s Distance = 123.0 
    var t Time = 300 

    // ... 
} 

компилируется и работает отлично. Что происходит за сценой, так это то, что буква 123.0 считается нетипизированным поплавком, а 300 считается нетипизированным int.

Я знаю, это звучит странно, но в основном эти значения не печатаются, поэтому Go пытается поместить их в тип слева. Вот почему вы можете написать var f float64 = 1, хотя 1 не является поплавком. Но вы не можете написать var f float64 = int(1), потому что 1 становится типизированным int, который не может быть переведен в float64.

Поэтому следующий не будет работать:

func main() { 
    var distance float64 = 123.0 
    var time float64 = 300 

    var s Distance = distance 
    var t Time = time 

    // ... 
} 
+2

Чтобы быть точным, в Go нет «кастинга» и преобразование при присваивании по-прежнему является преобразованием типа, т. е. 'var s Distance = 123.0' эквивалентно' s: = Distance (123.0) '. – JimB

0

Вы не можете делать неявные отбрасывания между пользовательскими типами - Go строго типизирован.

Я знаю, что это всего лишь маленький пример, но, возможно, вам действительно не нужны эти пользовательские типы?

package main 

import "fmt" 

func speed(distance float64, time float64) float64 { 
    return distance/time 
} 

func main() { 
    s := 123.0 
    t := 300.0 
    fmt.Println(speed(s, t)) 
} 
Смежные вопросы