编写转换函数的最佳方法

时间:2020-03-05 18:52:14  来源:igfitidea点击:

假设我正在编写一个在温度标度之间转换的函数。我想至少支持摄氏,华氏和开尔文。最好将源比例尺和目标比例尺作为函数的单独参数或者某种组合参数传递?

示例1的单独参数:
函数convertTemperature("摄氏度","华氏度",22)

示例2的组合参数:
函数convertTemperature(" c-f",22)

函数内部的代码可能在其中起作用。使用两个参数,确定我们将要使用的公式的逻辑稍微复杂一些,但是单个参数感觉不对。

有什么想法吗?

解决方案

回答

选择第一个选项,但不要使用原义字符串(容易出错),如果语言支持,则采用常量值或者枚举,如下所示:

convertTemperature (TempScale.CELSIUS, TempScale.FAHRENHEIT, 22)

回答

我的投票是转换类型的两个参数,一个用于值(如第一个示例)。但是,我将使用枚举而不是字符串文字。

回答

如果语言允许,请使用枚举来表示单位规格。

我想说里面的代码用两个会更容易。我要有一个包含预加,多加和后加的表,并通过一个单元的项目运行该值,然后反过来通过另一个单元的项目运行该值。基本上将输入温度转换为内部的公共基值,然后转换为其他单位。整个功能将由表驱动。

回答

取决于我们要进行多少次转化。我可能会选择一个作为枚举给出的参数:考虑此转换的扩展版本。

enum Conversion
{
  CelsiusToFahrenheit,
  FahrenheitToCelsius,
  KilosToPounds
}

Convert(Conversion conversion, X from);

现在,我们在调用点1处具有健全的类型安全性,无法提供正确类型的参数,这些参数会给出错误的运行时结果。考虑替代方案。

enum Units
{
  Pounds,
  Kilos,
  Celcius,
  Farenheight
}

Convert(Unit from, Unit to, X fromAmount);

我可以安全打个电话

Convert(Pounds, Celcius, 5, 10);

但是结果是没有意义的,我们将不得不在运行时失败。是的,我知道我们目前只在处理温度,但是一般概念仍然成立(我相信)。

回答

我将对温度类型进行枚举,然后传入2个比例参数。诸如此类(在C#中):

public void ConvertTemperature(TemperatureTypeEnum SourceTemp,
                               TemperatureTypeEnum TargetTemp, 
                               decimal Temperature)
{}

Answer

A few things:

I'd use an enumerated type that a syntax checker or compiler can check rather than a string that can be mistyped. In Pseudo-PHP:

define ('kCelsius', 0); define ('kFarenheit', 1); define ('kKelvin', 2);
$a = ConvertTemperature(22, kCelsius, kFarenheit);

Also, it seems more natural to me to place the thing you operate on, in this case the temperature to be converted, first. It gives a logical ordering to your parameters (convert -- what? from? to?) and thus helps with mnemonics.

Answer

I would choose 

以及此方法可避免的错误的示例:

// Freezing
        Debug.Assert(new FarenheitTemperature(32).ToCelcius().Equals(new CelciusTemperature(0)));
        Debug.Assert(new CelciusTemperature(0).ToFarenheit().Equals(new FarenheitTemperature(32)));

        // crossover
        Debug.Assert(new FarenheitTemperature(-40).ToCelcius().Equals(new CelciusTemperature(-40)));
        Debug.Assert(new CelciusTemperature(-40).ToFarenheit().Equals(new FarenheitTemperature(-40)));

剩下的练习是添加开尔文转换。

回答

在C(和可能是Java)中,最好创建一个Temperature类,将温度私下存储为Celcius(或者其他任何形式),并且具有Celcius,Fahrenheit和Kelvin属性,这些属性可以在get和set语句中为我们进行所有转换?

回答

顺便说一句,实现问题的建议并不需要更多的工作来实现三参数版本。

这些都是线性函数,因此我们可以实现类似

CelciusTemperature theOutbackInAMidnightOilSong = new CelciusTemperature(45);
        FarenheitTemperature x = theOutbackInAMidnightOilSong; // ERROR: Cannot implicitly convert type 'CelciusTemperature' to 'FarenheitTemperature'

最后一个布尔值指示要进行正向转换还是反向转换。

使用转换技术,我们可以为X-> Kelvin设置比例/加成对。当我们收到将格式X转换为Y的请求时,可以先运行X-> Kelvin,然后通过反转Y-> Kelvin进程(将最后一个布尔值翻转到LinearConvert)来运行Kelvin->Y。

这项技术在convert函数中为我们提供了4行实际代码,并且为每种类型之间需要转换的数据提供了一条数据。

回答

类似于@Rob @wcm和@David解释的...

float LinearConvert(float in, float scale, float add, bool invert);

回答

我想我会朝一个方向或者另一个方向全力以赴。我们可以编写一种迷你语言,像单位一样进行各种转换:

public class Temperature
{
    private double celcius;

    public static Temperature FromFarenheit(double farenheit)
    {
        return new Temperature { Farhenheit = farenheit };
    }

    public static Temperature FromCelcius(double celcius)
    {
        return new Temperature { Celcius = celcius };
    }

    public static Temperature FromKelvin(double kelvin)
    {
        return new Temperature { Kelvin = kelvin };
    }

    private double kelvinToCelcius(double kelvin)
    {
        return 1; // insert formula here
    }

    private double celciusToKelvin(double celcius)
    {
        return 1; // insert formula here
    }

    private double farhenheitToCelcius(double farhenheit)
    {
        return 1; // insert formula here
    }

    private double celciusToFarenheit(double kelvin)
    {
        return 1; // insert formula here
    }

    public double Kelvin
    {
        get { return celciusToKelvin(celcius); }
        set { celcius = kelvinToCelcius(value); }
    }

    public double Celcius
    {
        get { return celcius; }
        set { celcius = value; }
    }

    public double Farhenheit
    {
        get { return celciusToFarenheit(celcius); }
        set { celcius = farhenheitToCelcius(value); }
    }
}

或者使用像最近的Convert :: Temperature Perl模块那样的单个函数:

$ units 'tempF(-40)' tempC
    -40

但这提出了一个重要的观点-我们正在使用的语言是否已经具有转换功能?如果是这样,他们使用什么编码约定?因此,如果语言是C,则最好遵循atoi和strtod库函数的示例(未经测试):

use Convert::Temperature;

my $c = new Convert::Temperature();

my $res = $c->from_fahr_to_cel('59');

在撰写这篇文章时,我遇到了一篇关于使用emacs转换日期的非常有趣的文章。本主题的要点是它使用了一种"每次转换函数"样式。另外,转换可能非常晦涩。我倾向于使用SQL进行日期计算,因为该代码中似乎没有很多错误。将来,我将研究使用emacs。

回答

我希望有某种方法可以接受多个答案。根据每个人的建议,我想我会坚持使用多个参数,将字符串更改为枚举/常量,并将要转换的值移动到参数列表中的第一个位置。在函数内部,我将使用Kelvin作为共同的中间立场。

以前,我为每次转换编写了单独的函数,并且整个convertTemperature()函数仅仅是具有嵌套switch语句的包装器。我同时使用经典的ASP和PHP进行编写,但是我想让问题对任何语言都开放。

回答

这是我对此的看法(使用PHP):

double fahrtocel(double tempF){
    return ((tempF-32)*(5/9));
}

double celtofahr(double tempC){
    return ((9/5)*tempC + 32);
}

基本上,$ input值将转换为标准的摄氏温度标度,然后再次转换回$ output标度的一个功能可以将其全部控制。 =)

代码数量不匹配