Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Coding style 编写转换函数的最佳方法_Coding Style - Fatal编程技术网

Coding style 编写转换函数的最佳方法

Coding style 编写转换函数的最佳方法,coding-style,Coding Style,假设我正在编写一个函数,在温度刻度之间进行转换。我想至少支持摄氏度、华氏度和开尔文。传递源比例和目标比例作为函数的单独参数,还是某种组合参数更好 示例1-单独的参数: 功能转换器温度(“摄氏度”、“华氏度”、22度) 示例2-组合参数: 功能转换器温度(“c-f”,22) 函数中的代码可能就是它的作用所在。有了两个参数,确定我们将要使用的公式的逻辑稍微复杂一些,但是一个参数不知怎么的感觉不正确 想法?使用第一个选项,但不允许使用文本字符串(容易出错),而是使用常量值或枚举(如果您的语言支持),如

假设我正在编写一个函数,在温度刻度之间进行转换。我想至少支持摄氏度、华氏度和开尔文。传递源比例和目标比例作为函数的单独参数,还是某种组合参数更好

示例1-单独的参数: 功能转换器温度(“摄氏度”、“华氏度”、22度)

示例2-组合参数: 功能转换器温度(“c-f”,22)

函数中的代码可能就是它的作用所在。有了两个参数,确定我们将要使用的公式的逻辑稍微复杂一些,但是一个参数不知怎么的感觉不正确


想法?

使用第一个选项,但不允许使用文本字符串(容易出错),而是使用常量值或枚举(如果您的语言支持),如下所示:

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

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

如果您的语言允许,请使用枚举作为单元规范


我想说,里面的代码会更容易与两个。我将有一个包含预添加、多个和后添加的表,并对一个单元的项运行值,然后对另一个单元的项反向运行值。基本上将输入温度转换为内部的公共基值,然后输出到另一个单位。整个函数都是表驱动的。

取决于要进行的转换次数。我可能会选择一个参数,作为枚举:考虑这个扩展版本的转换。< /P>
enum Conversion
{
  CelsiusToFahrenheit,
  FahrenheitToCelsius,
  KilosToPounds
}

Convert(Conversion conversion, X from);
现在,您在调用点具有sane类型安全性—无法提供正确类型的参数,而这些参数会给出错误的运行时结果。考虑另一种选择。

enum Units
{
  Pounds,
  Kilos,
  Celcius,
  Farenheight
}

Convert(Unit from, Unit to, X fromAmount);
我可以打电话

Convert(Pounds, Celcius, 5, 10);

但是结果是没有意义的,你必须在运行时失败。是的,我知道你现在只讨论温度,但一般的概念仍然成立(我相信)。

我会对温度类型进行枚举,并传入两个刻度参数。类似于(在c中):


公共温度(TemperatureTypeNum SourceTemp,
目标温度,
十进制温度)
{}

有几件事:

  • 我会使用语法检查器或编译器可以检查的枚举类型,而不是可能键入错误的字符串。在伪PHP中:

    定义('kCelsius',0);定义('kFarenheit',1);定义('kKelvin',2); $a=转换温度(22,克塞尔修斯,克法伦海特)

而且,对我来说,把你操作的东西放在上面似乎更自然,在这种情况下,首先是要转换的温度。它为您的参数提供了一个逻辑顺序(convert--what?from?to?),从而有助于记忆功能。

我会选择

示例1-单独参数:函数转换器温度(“摄氏度”、“华氏度”、22度)

否则,在函数定义中,您必须将“c-f”解析为“摄氏度”和“华氏度”,以获得所需的转换比例,这可能会变得混乱


如果你正在为用户提供类似谷歌搜索框的东西,那么拥有像“c-f”这样的便捷快捷方式对他们来说很好。不过,在下面,我会在调用convertTemperature()之前将外部函数中的“c-f”转换为“摄氏度”和“华氏度”

将温度从一个刻度转换为另一个刻度的功能。

在我看来,将源标度和目标标度作为单独的参数传递更为自然。我绝对不想试图掌握第一个论点的格式。

在写这样的设计时,我想自己,“如果我需要添加一个额外的单元,什么样的设计会使它最容易实现?”这样做,我得出结论,Enum最容易实现,原因如下:

1) 添加新值很容易。 2) 我避免做字符串比较

但是,如何编写转换方法?3p2是6。这意味着有6种不同的摄氏度、华氏度和开尔文的组合。如果我想添加一个新的温带格式“foo”呢?这意味着4p2,也就是12!再来两杯?5p2=20个组合。再来三个?6p2=30个组合


您可以很快看到,每次额外的修改都需要对代码进行越来越多的更改。因为这个原因,我不做直接转换!相反,我进行中间转换。我会选择一个温度,比如开尔文。最初,我会转换成开尔文。然后我将开尔文转换成所需的温度。是的,它确实会导致额外的计算。然而,它使代码的缩放变得更加容易。添加一个新的温度单位通常只会对代码进行两次新的修改。简单。

如果使用第一种方法,您的函数将更加健壮。如果需要添加另一个比例,则需要再处理一个参数值。在第二种方法中,添加另一个比例意味着添加列表中已有比例的值,乘以2。(例如,要将K添加到C和F,必须添加K-C、K-F、C-K和C-F。)

构建程序的一种好方法是,首先将输入的任何内容转换为任意选择的中间刻度,然后从该中间刻度转换为输出刻度


更好的方法是为各种比例尺建立一个小的坡度和截距库,只需查找传入和传出比例尺的数字,然后在一个通用步骤中进行计算。

取决于语言

通常,我会对枚举使用单独的参数

如果它是一种面向对象的语言,那么我建议使用一个temperature类,该类的温度按照您喜欢的方式存储在内部,然后使用函数以所需的任何单位输出:

摄氏温度();//返回temperatu

public void ConvertTemperature(TemperatureTypeEnum SourceTemp,
                               TemperatureTypeEnum TargetTemp, 
                               decimal Temperature)
{}
interface ITemperature
{
     CelciusTemperature ToCelcius();
     FarenheitTemperature ToFarenheit();
}

struct FarenheitTemperature : ITemperature
{
    public readonly int Value;
    public FarenheitTemperature(int value)
    {
        this.Value = value;
    }

    public FarenheitTemperature ToFarenheit() { return this; }
    public CelciusTemperature ToCelcius()
    {
        return new CelciusTemperature((this.Value - 32) * 5 / 9);
    }

}

struct CelciusTemperature
{
    public readonly int Value;
    public CelciusTemperature(int value)
    {
        this.Value = value;
    }

    public CelciusTemperature ToCelcius() { return this; }
    public FarenheitTemperature ToFarenheit()
    {
        return new FarenheitTemperature(this.Value * 9 / 5 + 32);
    }
}
        // 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)));
        CelciusTemperature theOutbackInAMidnightOilSong = new CelciusTemperature(45);
        FarenheitTemperature x = theOutbackInAMidnightOilSong; // ERROR: Cannot implicitly convert type 'CelciusTemperature' to 'FarenheitTemperature'
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); }
    }
}
$ units 'tempF(-40)' tempC
    -40
use Convert::Temperature;

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

my $res = $c->from_fahr_to_cel('59');
double fahrtocel(double tempF){
    return ((tempF-32)*(5/9));
}

double celtofahr(double tempC){
    return ((9/5)*tempC + 32);
}
function Temperature($value, $input, $output)
{
    $value = floatval($value);

    if (isset($input, $output) === true)
    {
        switch ($input)
        {
            case 'K': $value = $value - 273.15; break; // Kelvin
            case 'F': $value = ($value - 32) * (5 / 9); break; // Fahrenheit
            case 'R': $value = ($value - 491.67) * (5 / 9); break; // Rankine
        }

        switch ($output)
        {
            case 'K': $value = $value + 273.15; break; // Kelvin
            case 'F': $value = $value * (9 / 5) + 32; break; // Fahrenheit
            case 'R': $value = ($value + 273.15) * (9 / 5); break; // Rankine
        }
    }

    return $value;
}