像常量一样工作的变量的命名约定

发布于 2024-08-02 21:07:47 字数 187 浏览 2 评论 0原文

我有一个像常量一样使用的变量(它永远不会改变)。我无法将其声明为常量,因为该值是在运行时添加的。

您会将变量名称大写以帮助自己理解数据的含义吗?

或者您会因为这违反了惯例并使事情变得更加混乱?

更大的问题:
即使场景不是典型的惯例,但足够接近,可以帮助您个人理解事物,您是否遵循惯例?

I have a variable that I'm using like a constant (it will never change). I can't declare it as a constant because the value gets added at runtime.

Would you capitalize the variable name to help yourself understand that data's meaning?

Or would you not because this defies convention and make things more confusing?

The larger question:
Do you follow conventions even if the scenario isn't typical of the convention, but close enough that it might help you, personally, to understand things?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

轻许诺言 2024-08-09 21:07:48

首先,遵循项目的编码标准。您应该为阅读代码的其他人编写代码,而不是为您自己编写代码。您的个人偏好不应优先于项目范围的规则和约定等。

在缺乏项目编码标准的情况下,您应该遵循您正在处理的语言的“最佳实践”。

在 Java 中,最佳实践是您应该使用驼峰式大小写标识符声明伪常量。这就是 Sun Java 编码标准的规定,也是绝大多数专业 Java 开发人员所使用的。

在 C 和 C++ 中,(经典)约定是全部大写用于定义为预处理器符号的常量。因此,由于这不是预处理器符号,因此您应该使用适合变量的编码标准。

伪常数不应该改变的事实不会阻止某人修改代码,使其实际上发生变化,无论是有意还是无意。如果您使用/滥用使标识符看起来像一个真正的常量的编码约定,那么您将成为问题的一部分:

  1. 尝试读取/调试您的代码的人将首先假设标识符是一个真正的常量而不去调查事实并非如此的可能性。
  2. 然后当他们看到宣言时,就会有很多喊叫和威胁
    弹出窗外。

实际上,处理伪常数的更好方法是将其封装。在 Java 中,您可以将其声明为私有成员并提供 getter 和 setter。设置器应该做一些事情来防止伪常数在第一次设置后被更改。任何像样的 Java JIT 编译器都会内联一个简单的 getter,因此这不会影响运行时性能。

First of all, follow your project's coding standards. You should be coding for other people reading the code, not yourself. Your personal preferences should not take precedence over project-wide rules and conventions, etc.

In the absence of a project coding standard you should follow "best practice" for the language you are dealing with.

In Java, best practice is that you should declare a pseudo-constant with a camel case identifier. That's what the Sun Java coding standard says, and that is what the vast majority of professional Java developers use.

In C and C++ the (classical) convention is that all-caps is used for constants defined as preprocessor symbols. So since this is not a preprocessor symbol, you should use whatever your coding standard says is appropriate for a variable.

The fact that the pseudo-constant is not supposed to change won't stop someone from modifying the code so that it actually changes, accidentally or deliberately. If you use / abuse a coding convention that makes the identifier look like a real constaint, you will be part of the problem:

  1. Someone trying to read / debug your code will first assume the identifier is a real constant and not investigate the possibility thatit is not.
  2. Then when they do lookat the declaration, there will be alot of shouting and threats of
    defenestration.

Actually, a better way to deal with a pseudo-constant is to encapsulate it. In Java, you would declare it as private member and provide a getter and setter. The setter should do something to prevent the pseudo-constant from being changed after it has been set the first time. Any decent Java JIT compiler will inline a simple getter, so this should not affect runtime performance.

双马尾 2024-08-09 21:07:48

提供错误信息通常不是最佳做法。

当某事物仅仅当前没有改变时,隐含地声称它是一个常量,就是给出错误的信息。

Giving wrong information is generally not best practise.

Implicitly claiming something is a constant, when it is merely currently not changed, is giving out wrong information.

滥情空心 2024-08-09 21:07:48

我不确定这在您选择的语言中是否合法,但在 C++ 中,这将符合您的目的:

#include <iostream>

int main()
{
    int i = 0;
    std::cin >> i;

    const int CONST = i; 
    std::cout << CONST; //displays i

    system("PAUSE"); 
    return 0;
}

我不确定这是否是道德上的事情,但这确实解决了您的问题(除非您真的需要你的记忆)。

I'm not sure if this is legal in your language of choice, but in C++, this would work for your purpose:

#include <iostream>

int main()
{
    int i = 0;
    std::cin >> i;

    const int CONST = i; 
    std::cout << CONST; //displays i

    system("PAUSE"); 
    return 0;
}

I'm not sure if this is a moral thing to do, but this does solve your problem (unless you really need your memory).

无言温柔 2024-08-09 21:07:48

就像其他任何事情一样 - 需要范围和上下文才能知道某些事物以何种方式保持不变。所以——没有办法让所有人都满意。

遵循您选择的语言中使用的风格 - 80% 的情况下,这样就足够清晰了。另一种选择是一个高度过度的命名系统,它牺牲了生产力以换取理想的技术正确性(如果你能实现它,很少有人会真正欣赏它。)

Just like anything else - scope and context are required to know in what way something is constant. So - there's no way to to satisfy everyone.

Follow the style used in your language of choice - 80% of the time, that will be clear enough. The alternative is a highly over-though nameing system that sacrifices productivity for ideal technical correctness (which few people will even really appreaciate if you can ever achieve it.)

彻夜缠绵 2024-08-09 21:07:48

一个问题是:什么样的变量?

对于静态变量,在我所说的“启动时间”之后不会改变,因为缺乏更好的术语,我使用 ALL_CAPS ...对于全局变量也是如此(如果语言完全支持它们) )...

传达语义实际上是命名约定的要点,并且看到 ALL_CAPS 清楚地表明,a)我不会写入它 b)我可以缓存它(例如,到局部变量,或者在 AS3 中甚至是一个实例)变量是有道理的,因为静态访问非常慢)...

它是否是一个“真正的常量”并不重要...这更多的是一个实现细节,应该隐藏起来(可靠!信息隐藏很好,很重要,但至关重要的是,共享的信息是可以信任的!)...它确实可以交换...例如,我经常开始构建应用程序与一些包含一些静态常量的硬编码配置。 ..后来,我决定我不希望它被硬编码,而是来自一些配置文件,所以我加载它,并且在启动过程中,我初始化所有伪常量......实际的应用程序仍然处理它们作为常量,因为启动后,这就是这些值...这对我来说似乎完全有效...

在实例级别,我不是 100% 确定,如果我遇到过这样的情况,我可能会非常当然,某些字段永远不会改变...通常,这使得类不灵活...

除此之外,您通常可以声明只读属性,以产生编译时错误,这也是一件好事...

one question would be: what kind of variable?

in the case of static variables, that don't change after what i'd call "boot-time" for the lack of a better term, i use ALL_CAPS ... same thing for global variables (if the language supports them at all) ...

communicating semantics is actually the point of naming conventions, and seeing an ALL_CAPS clearly states, that a) i will not write to it b) i can cache it (to a local variable for example, or in AS3 even an instance variable makes sense, since static access is very slow) ...

whether it's a "real constant" or not does not really matter ... that's more of an implementation detail, that should be hidden away (reliably! information hiding is good, and important, but it is crucial, that the information that is shared, can be trusted!) ... it can really be exchanged ... for example, i often start building apps vs. some hardcoded config, containing some static constants ... later, i decide that i don't want this to be hardcoded, but rather coming from some config file, so i load it, and during boot process, i init all the pseudo-constants ... the actuall app still treats them as constants, because after booting, that is what these values are ... this seems perfectly valid to me ...

at instance level, i am not 100% sure, if i ever ran into a case, where i could be very certain, that some field would never change ... usually, this makes the class unflexible ...

other than that, you can usually declare readonly properties, to have compile time errors, which is also a good thing to have ...

太阳哥哥 2024-08-09 21:07:47

如果它能帮助您(和其他人)在六个月后理解您的代码,那就去做吧。如果不会,那就不要。真的就是这么简单。

就我个人而言,我会利用它。这是 Java 中的约定,由于其面向对象的性质,常量总是在运行时分配。知道如果我不小心分配给它,我下次扫描那段代码时肯定会注意到,我会更舒服。

If it will aid you (and everybody else) in understanding your code six months down the line, do it. If it won't, don't. It's really that simple.

Personally, I would capitalise it. This is the convention in Java, where constants are always allocated at runtime due to its object-oriented nature. I'd be much more comfortable knowing that if I accidentally assigned to it, I'd definitely notice the next time I scanned through that chunk of code.

寂寞笑我太脆弱 2024-08-09 21:07:47

我不认为我的个人信息在这里是最重要的——如果我已经编写了代码,那么我已经比其他任何人都更有能力在将来需要时重新跟踪它;所以我把“其他人”放在首位——现在或未来的队友需要(理想情况下)像我一样彻底地理解代码。

此外,将强制代码审查作为向代码库提交任何内容的先决条件(这是一个很好的实践,也是我现在雇主的可靠规则),如果我疏忽了我的注意力,我很可能会被召集起来(它确实发生 - 这就是为什么我喜欢那些强制性的代码审查,适用于我自己以及其他人!-)。

“在启动时仅设置一次变量”是一个足够特殊的情况,可能值得添加到您团队的指南中 - 将其视为“比变量更接近常量”可能很有意义,但这只有在以下情况下才有帮助:整个代码库一致使用相同的规则/指南。如果规则不存在,我会检查是否就添加它达成共识;否则,我不会为了个人品味而违反准则……这是“无私编程”和“代码库的团队所有权”的根源,这是我热情服务的两条原则。

顺便说一句,如果我在编码指南方面处于单人团队中(这种情况确实发生了,尽管这不是最佳情况;),我认为我自己可以毫无困难地获得一致的共识,即处理“启动时设置一次”根据命名约定,变量作为常量!-)。但对于更大的团队来说,工作量就更大,而且两种情况都可能发生。

I don't consider my personals need to be paramount here -- if I've written the code, I'm already better placed to retrace it in the future if and when that's needed, than anybody else; so it's the "anybody else" I put first and foremost -- a present or future teammate that will need to understand the code (ideally) as thoroughly as I do.

Besides, with mandatory code reviews as a prereq to committing ANYthing to the codebase (an excellent practice, and the unfailing rule at my present employer), I'm likely to be called up on it should I ever let my attention slip (it does happen -- which is why I LOVE those mandatory code reviews, as applied to myself as well as everybody else!-).

A "variable set only once at startup" is a special-enough case that may be worth adding to your team's guidelines -- treating it as "closer to a constant than a variable" may make a lot of sense, but that only helps if the same rule/guideline is used consistently across the codebase. If the rule is not there I would check if there's consensus about adding it; otherwise, I would NOT break the guidelines for the sake of my personal tastes... that's the root of "egoless programming" and "team ownership of the codebase", two principles I serve with burning ardor.

BTW, were I on a single-person team in terms of coding guidelines (it happens, though it's not an optimal situation;), I think I'd have no trouble gaining unanimous consensus by myself that treating "set-once at startup" variables as constants in terms of naming conventions!-). But with a larger team, that's more work, and it could go either way.

记忆里有你的影子 2024-08-09 21:07:47

将其封装起来。

#include <iostream>

class ParamFoo
{
    public:
        static void initializeAtStartup(double x);
        static double getFoo();
    private:
        static double foo_;
};

double ParamFoo::foo_;

void ParamFoo::initializeAtStartup(double x)
{
    foo_ = x;
}

double ParamFoo::getFoo()
{
    return foo_;
}

int main(void)
{
    ParamFoo::initializeAtStartup(0.4);
    std::cout << ParamFoo::getFoo() << std::endl;
}

这应该非常清楚地表明,除了在应用程序启动时之外,您不应该在其他任何地方设置该值。如果您想要增强保护,可以添加一些私有保护 boolean 变量,以便在多次调用 initializeAtStartup 时抛出异常。

Encapsulate it.

#include <iostream>

class ParamFoo
{
    public:
        static void initializeAtStartup(double x);
        static double getFoo();
    private:
        static double foo_;
};

double ParamFoo::foo_;

void ParamFoo::initializeAtStartup(double x)
{
    foo_ = x;
}

double ParamFoo::getFoo()
{
    return foo_;
}

int main(void)
{
    ParamFoo::initializeAtStartup(0.4);
    std::cout << ParamFoo::getFoo() << std::endl;
}

This should make it pretty clear that you shouldn't be setting this value anywhere else but at the startup of the application. If you want added protection, you can add some private guard boolean variable to throw an exception if initializeAtStartup is called more than once.

新一帅帅 2024-08-09 21:07:47

我会将其命名为变量,我更喜欢保持命名一致。
正如 Rob 已经建议的那样,只读怎么样(至少在 C# 中可用)。
或者没有 setter 的属性。

I would name it as a variable, I prefer to keep my naming very consistent.
As Rob already suggested, what about readonly (available in C# at least).
Or a property with no setter.

微暖i 2024-08-09 21:07:47

我的第一印象是,“在运行时设置,然后永远不会改变”的东西是一个常数,只有业务规则是不变的。另外,您应该使用修改器/访问器,因为使用全部大写很难保证“常量”。

public class BadClass
{ 
    public static final double PI = 3.1;     
      // PI is very constant.  Not according to the business roles modeled by my 
      // application, but by nature.  I don't have a problem making this publicly
      // accessible--except that [Math] already does, with much better precision)

    public static /*final*/ int FOO = null;
      // FOO is constant only by convention.  I cannot even enforce its "constness".
      // Making it public means that my enemies (overtime, for example) can change 
      // the value (late night programming), without telling me.
}

相反,

public class BetterClass
{
    public static final double PI = 3.1;
    private /*final*/ Integer foo = null; 

    public int getFoo() {
        return this.foo.intValue();
    }
    public void setFoo(int value) {
        // The business rules say that foo can be set only once.
        // If the business rules change, we can remove this condition 
        // without breaking old code.
        if ( null == this.foo ) {
           this.foo = value;
        } else {
           throw new IllegalStateException("Foo can be set only once.");
        }
    }
}

如果您始终使用变元来设置值,即使在 [BetterClass] 本身内,您也知道 foo 的“constness”不会被违反。当然,如果有人要直接设置 foo 的值(我需要在凌晨 2:00 之前停止工作!),仍然没有保证。但类似的事情应该在代码审查时指出。

所以我的建议是将 foo 视为普通的成员变量——对于几乎 const 的东西不需要有特殊的命名约定。

但是,即使在私有变量上,也要使用修改器/访问器。这些通常非常快,您可以在其中强制执行业务规则。这应该是你们的约定。

(如果您正在为嵌入式医疗设备编写代码,请假装您从未见过此帖子)。

My immediate impression is that something that you "set at runtime, then never change" is a constant, only so far as the business rules are constant. Also, you should be using mutators/accessors, since using ALL CAPS can hardly guarantee "constness".

public class BadClass
{ 
    public static final double PI = 3.1;     
      // PI is very constant.  Not according to the business roles modeled by my 
      // application, but by nature.  I don't have a problem making this publicly
      // accessible--except that [Math] already does, with much better precision)

    public static /*final*/ int FOO = null;
      // FOO is constant only by convention.  I cannot even enforce its "constness".
      // Making it public means that my enemies (overtime, for example) can change 
      // the value (late night programming), without telling me.
}

Instead,

public class BetterClass
{
    public static final double PI = 3.1;
    private /*final*/ Integer foo = null; 

    public int getFoo() {
        return this.foo.intValue();
    }
    public void setFoo(int value) {
        // The business rules say that foo can be set only once.
        // If the business rules change, we can remove this condition 
        // without breaking old code.
        if ( null == this.foo ) {
           this.foo = value;
        } else {
           throw new IllegalStateException("Foo can be set only once.");
        }
    }
}

If you always use the mutator to set the value, even within [BetterClass] itself, you know that the foo's "constness" will not be violated. Of course, if someone is going to set the value of foo directly (I need to quit working before 2:00 am!), there are still no guarantees. But something like that should be pointed out at code review.

So my recommendation is to treat foo as a normal member variable--there doesn't need to be a special naming convention for something that is almost const.

However, use mutators/accessors, even on private variables. These are typically very fast, and you can enforce business rules inside of them. This should be you convention.

(If you are writing code for embedded medical devices, pretend that you never saw this posting).

冬天旳寂寞 2024-08-09 21:07:47

是否可以将其标记为只读?那么约定就不再那么重要了。

is it possible to mark it as readonly? Then conventions are not as important.

美男兮 2024-08-09 21:07:47

即使
场景不典型
惯例,但足够接近
就个人而言,可能会帮助您
了解事物吗?

当场景非典型时遵循约定可能会让其他人(甚至在一段时间后甚至是你)感到困惑或减慢速度。我会避免给一个变量伪装成它不是的东西。

此外,您遇到这种非典型场景的事实可能表明,也许可以遵循其他一些更典型的范例。不过,我没有任何替代方案的直接建议。

Do you follow conventions even if the
scenario isn't typical of the
convention, but close enough that it
might help you, personally, to
understand things?

Following a convention when the scenario is atypical might confuse or slow down others (or even you, after a while.) I would avoid giving a variable the guise of something that it isn't.

Also, the fact that you have this atypical scenario could be an indication that perhaps some other, more typical paradigm could be followed. Though, I don't have any immediate suggestions for a alternative.

新雨望断虹 2024-08-09 21:07:47

我会将其大写(因为从设计角度来看,它比变量更恒定),并在其周围添加注释,说明其对应用程序的独特性。

I would make it capitalized (since it's more constant than variable from a design perspective) and add a comment around it stating its uniqueness to the application.

许久 2024-08-09 21:07:47

FWIW我自己的惯例是对#define和枚举使用全部大写。对于 const 变量,我要么不使用特定的约定,要么在使用时在名称前添加“k”前缀(对于“konstant”,而不是“c”)',它已经过度用于“count”或“char”等内容)。

我发现我喜欢“k”约定,并且可能会更频繁地使用它,甚至可能将它用于枚举,为可怕的预处理器宏保留尖叫的全大写标识符。

FWIW my own convention is to use all caps for #defines and for enums. For const variables I either use no particular convention, or when I do it's to prefix the name with a 'k' (for 'konstant' - not 'c' which is already over used for things like 'count' or 'char').

I'm finding that I like the 'k' convention and will probably use it more often, and may even use it for enums, reserving the screaming, all-caps identifiers for the dreaded preprocessor macros.

甜点 2024-08-09 21:07:47

惯例就是惯例。它们的作用是帮助代码易于理解。如果它们的选择不是太糟糕并且始终如一地应用,它们通常会这样做。最后一点可能是关于它们的最重要的事情:它们应该一致地应用

阻碍某些约定使代码更具可读性的一件事是,即使它们一致地应用(至少对于新手和在代码库之间切换的人来说),它们与其他约定发生冲突。在 C 和 C++ 中,我知道关于使用 ALL_CAPS 名称的两个常见约定:

  • 为预处理器保留它们;我更喜欢这个,因为预处理器标识符很特殊:它们不遵守通常的作用域规则,并且防止与它们发生冲突很重要

  • 将它们用作常量(宏和枚举器)。

如果您将它们用于逻辑上恒定的事物(实际上是可变的),那么除了不熟悉之外还会出现两个问题:

  • 在语言需要常量表达式的地方(如数组大小)不可用

  • 我的经验告诉我,维护往往会使它们变得比现在更不恒定。

Conventions are just that, conventions. They are there to help the code understandable. They usually do if they are not too badly chosen and if they are applied consistently. The last point is probably the most important thing about them: they should be applied consistently.

One thing which prevent some conventions to make code more readable even when they are applied consistently -- at least for new comers and people switching between code base -- is when they are conflicting with other conventions. In C and C++, I'm aware of two common conventions about the use of names in ALL_CAPS:

  • reserve them for the preprocessor; that one has my preference as the preprocessor identifier are special: they don't obey usual scoping rule and preventing clashes with them is important

  • use them for constant (macro and enumerators).

Two problems comes in addition to the unfamiliarity if you use them for logically constant things which are in fact variable:

  • they aren't usable in places (like array size) where the language expect constant expression

  • my experience teach me that maintenance will tend to make them even less constant that they are now.

作业与我同在 2024-08-09 21:07:47

创建一个具有单个私有静态字段的包装类。创建一个 initField(..) 和一个 getField(..) 静态方法。如果静态字段不为空,则 initField 会抛出/断言/其他错误。 (对于基元,您可能必须使用基元和布尔值来跟踪初始化。)

在 java 中,我更喜欢将这些类型的变量作为系统属性传递。然后,静态类可以执行以下操作:

public final int MY_INT = Integer.getInteger("a.property.name");

您还可以使用属性文件(请参阅 java.util.Properties),而不是使用 -D 来指定它。然后你得到:

public class Foo {

public static final int MY_INT;

static {
Properties p = new Properties();
try{
p.load( new FileInputStream("app.props"):
} catch(IOException e) {
//SWALLOW or RETHROW AS ERROR
}
MY_INT=Integer.parseInt( p.getProperty("my.int","17") ); //17 is default if you swallo IOException
}
...
}

Create a wrapper class with a single private static field. Create an initField(..) and a getField(..) static method. initField throws/asserts/otherwise errors if the static field is not null. (For primitives, you may have to use a primitive and a boolean to track initialization.)

In java, I prefer to pass these types of variables in as system properties. A static class can then do something like:

public final int MY_INT = Integer.getInteger("a.property.name");

You could also use a property file (see java.util.Properties) instead of using -D to specify it. Then you get:

public class Foo {

public static final int MY_INT;

static {
Properties p = new Properties();
try{
p.load( new FileInputStream("app.props"):
} catch(IOException e) {
//SWALLOW or RETHROW AS ERROR
}
MY_INT=Integer.parseInt( p.getProperty("my.int","17") ); //17 is default if you swallo IOException
}
...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文