# Temperature Scale Converter in Golang

Problem statement:

Write a program that converts all given temperatures from a given input temperature scale to a given output temperature scale. The temperature scales to be supported are Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Rømer, Réaumur.

Synopsis: tempconv INPUT_SCALE OUTPUT_SCALE [TEMPERATURE]...

The INPUT_SCALE and OUTPUT_SCALE shall be given as follows:

• K for Kelvin
• C for Celsius
• F for Fahrenheit
• R for Rankine
• D for Delisle
• N for Newton
• Rø for Rømer
• Ré for Réaumur.

Example:

tempconv K C 0 273.15 373.15
-273.15
0.0
100.0


My solution in Golang:

package main

import (
"fmt"
"os"
"strconv"
)

type TempConv struct {
toKelvin   func(other float64) float64
fromKelvin func(kelvin float64) float64
}

var scales = map[string]TempConv{}

func init() {
register := func(toKelvin func(other float64) float64, fromKelvin func(kelvin float64) float64, names []string) {
conv := TempConv{toKelvin, fromKelvin};
for _, name := range names {
scales[name] = conv
}
}

register(func(celsius    float64) float64 { return celsius + 273.15                 }, func(kelvin float64) float64 { return kelvin - 273.15                 }, []string{"°C", "C", "c"});
register(func(kelvin     float64) float64 { return kelvin                           }, func(kelvin float64) float64 { return kelvin                          }, []string{"K"});
register(func(fahrenheit float64) float64 { return (fahrenheit + 459.67) * 5 / 9    }, func(kelvin float64) float64 { return kelvin * 9 / 5 - 459.67         }, []string{"°F", "F", "f"});
register(func(delisle    float64) float64 { return 373.15 - delisle * 2 / 3         }, func(kelvin float64) float64 { return (373.15 - kelvin) * 3 / 2       }, []string{"°De", "De", "DE", "de"});
register(func(newton     float64) float64 { return newton*100/33 + 273.15           }, func(kelvin float64) float64 { return (kelvin - 273.15) * 33 / 100    }, []string{"°N", "N", "n"});
register(func(rankine    float64) float64 { return rankine * 5 / 9                  }, func(kelvin float64) float64 { return kelvin * 9 / 5                  }, []string{"°R", "R", "r"});
register(func(réaumur    float64) float64 { return réaumur * 5 / 4 + 273.15         }, func(kelvin float64) float64 { return (kelvin - 273.15) * 4 / 5       }, []string{"°Ré", "°Re", "Ré", "RÉ", "ré", "Re", "RE", "re"});
register(func(rømer      float64) float64 { return (rømer - 7.5) * 40 / 21 + 273.15 }, func(kelvin float64) float64 { return (kelvin-273.15) * 21 / 40 + 7.5 }, []string{"°Rø", "°Ro", "Rø", "RØ", "rø", "Ro", "RO", "ro"});
}

func main() {
toKelvin := scales[os.Args[1]].toKelvin
fromKelvin := scales[os.Args[2]].fromKelvin
for _, arg := range os.Args[3:] {
inputTemp, _ := strconv.ParseFloat(arg, 64)
fmt.Println(fromKelvin(toKelvin(inputTemp)))
}
}


I'm aware that error handling is incomplete.

I'm particularly interested in the following feedback:

• Is there a smarter way to initialize scales without requiring an init() function?
• Is there a way to make the calls to register() shorter? I know golang doesn't have a terse lambda syntax with -> or => (or has it?), but maybe there's another way?