C++ 吗?有“与”像 Pascal 这样的关键字?

发布于 2024-08-21 10:14:48 字数 358 浏览 7 评论 0原文

Pascal中的with关键字可用于快速访问记录的字段。 有人知道 C++ 是否有类似的东西吗?

前任: 我有一个包含许多字段的指针,但我不想这样输入:

if (pointer->field1) && (pointer->field2) && ... (pointer->fieldn)

我真正想要的是 C++ 中的这样的内容:

with (pointer)
{
  if (field1) && (field2) && .......(fieldn)
}

with keyword in Pascal can be use to quick access the field of a record.
Anybody knows if C++ has anything similar to that?

Ex:
I have a pointer with many fields and i don't want to type like this:

if (pointer->field1) && (pointer->field2) && ... (pointer->fieldn)

what I really want is something like this in C++:

with (pointer)
{
  if (field1) && (field2) && .......(fieldn)
}

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

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

发布评论

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

评论(19

热鲨 2024-08-28 10:14:48

可能您能得到的最接近的是:(这只是一个学术练习。当然,您不能在这些人工 with 块的主体中​​使用任何局部变量!)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    struct withbar : Bar { void operator()() {
        cerr << field << endl;
    }}; static_cast<withbar&>(b)();
}

或者,更多一点恶魔般地,

#define WITH(T) do { struct WITH : T { void operator()() {
#define ENDWITH(X) }}; static_cast<WITH&>((X))(); } while(0)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    if ( 1+1 == 2 )
        WITH( Bar )
            cerr << field << endl;
        ENDWITH( b );
}

或在 C++0x 中

#define WITH(X) do { auto P = &X; \
 struct WITH : typename decay< decltype(X) >::type { void operator()() {
#define ENDWITH }}; static_cast<WITH&>((*P))(); } while(0)

        WITH( b )
            cerr << field << endl;
        ENDWITH;

Probably the closest you can get is this: (this is just an academic exercise. Of course, you can't use any local variables in the body of these artificial with blocks!)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    struct withbar : Bar { void operator()() {
        cerr << field << endl;
    }}; static_cast<withbar&>(b)();
}

Or, a bit more demonically,

#define WITH(T) do { struct WITH : T { void operator()() {
#define ENDWITH(X) }}; static_cast<WITH&>((X))(); } while(0)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    if ( 1+1 == 2 )
        WITH( Bar )
            cerr << field << endl;
        ENDWITH( b );
}

or in C++0x

#define WITH(X) do { auto P = &X; \
 struct WITH : typename decay< decltype(X) >::type { void operator()() {
#define ENDWITH }}; static_cast<WITH&>((*P))(); } while(0)

        WITH( b )
            cerr << field << endl;
        ENDWITH;
此刻的回忆 2024-08-28 10:14:48

不,没有这样的关键字。

no there is no such keyword.

友谊不毕业 2024-08-28 10:14:48

我喜欢使用:

    #define BEGIN_WITH(x) { \
        auto &_ = x;

    #define END_WITH() }

示例:

    BEGIN_WITH(MyStructABC)
    _.a = 1;
    _.b = 2;
    _.c = 3;
    END_WITH()

I like to use:

    #define BEGIN_WITH(x) { \
        auto &_ = x;

    #define END_WITH() }

Example:

    BEGIN_WITH(MyStructABC)
    _.a = 1;
    _.b = 2;
    _.c = 3;
    END_WITH()
晨曦÷微暖 2024-08-28 10:14:48

在 C++ 中,您可以将代码放入由指针引用的类的方法中。在那里您可以直接引用成员而不使用指针。让它内联,你几乎就得到了你想要的。

In C++, you can put code in a method of the class being reference by pointer. There you can directly reference the members without using the pointer. Make it inline and you pretty much get what you want.

沫离伤花 2024-08-28 10:14:48

尽管我主要在 Delphi 中进行编程,它有一个 with 关键字(因为 Delphi 是 Pascal 的衍生版本),但我不使用 with。正如其他人所说:它节省了一点打字时间,但阅读却变得更加困难。

在像下面的代码的情况下,可能很容易使用 with

cxGrid.DBTableView.ViewData.Records.FieldByName('foo').Value = 1;
cxGrid.DBTableView.ViewData.Records.FieldByName('bar').Value = 2;
cxGrid.DBTableView.ViewData.Records.FieldByName('baz').Value = 3;

使用 with 这看起来像这样,

with cxGrid.DBTableView.ViewData.Records do
begin
  FieldByName('foo').Value = 1;
  FieldByName('bar').Value = 2;
  FieldByName('baz').Value = 3;
end;

我更喜欢通过引入一个指向with 会指向同样的东西。像这样:

var lRecords: TDataSet;

lRecords := cxGrid.DBTableView.ViewData.Records;

lRecords.FieldByName('foo').Value = 1;
lRecords.FieldByName('bar').Value = 2;
lRecords.FieldByName('baz').Value = 3;

这样就不会出现歧义,您可以节省一些打字时间,并且代码的意图比使用 with 更清晰

Even though I program mostly in Delphi which has a with keyword (since Delphi is a Pascal derivative), I don't use with. As others have said: it saves a bit on typing, but reading is made harder.

In a case like the code below it might be tempting to use with:

cxGrid.DBTableView.ViewData.Records.FieldByName('foo').Value = 1;
cxGrid.DBTableView.ViewData.Records.FieldByName('bar').Value = 2;
cxGrid.DBTableView.ViewData.Records.FieldByName('baz').Value = 3;

Using with this looks like this

with cxGrid.DBTableView.ViewData.Records do
begin
  FieldByName('foo').Value = 1;
  FieldByName('bar').Value = 2;
  FieldByName('baz').Value = 3;
end;

I prefer to use a different technique by introducing an extra variable pointing to the same thing with would be pointing to. Like this:

var lRecords: TDataSet;

lRecords := cxGrid.DBTableView.ViewData.Records;

lRecords.FieldByName('foo').Value = 1;
lRecords.FieldByName('bar').Value = 2;
lRecords.FieldByName('baz').Value = 3;

This way there is no ambiguity, you save a bit on typing and the intent of the code is clearer than using with

眼前雾蒙蒙 2024-08-28 10:14:48

不,C++ 没有任何这样的关键字。

No, C++ does not have any such keyword.

撧情箌佬 2024-08-28 10:14:48

您可以获得的最接近的是方法链接

myObj->setX(x)
     ->setY(y)
     ->setZ(z)

用于设置多个字段并使用 对于命名空间。

The closest you can get is method chaining:

myObj->setX(x)
     ->setY(y)
     ->setZ(z)

for setting multiple fields and using for namespaces.

风透绣罗衣 2024-08-28 10:14:48

C++没有这样的功能。许多人认为 Pascal 中的“WITH”是一个问题,因为它会使代码含糊不清且难以阅读,例如很难知道 field1 是指针成员还是局部变量或其他东西。 Pascal 还允许多个 with 变量,例如“With Var1,Var2”,这使得它变得更加困难。

C++ does not have a feature like that. And many consider "WITH" in Pascal to be a problem because it can make the code ambiguous and hard to read, for example it hard to know if field1 is a member of pointer or a local variable or something else. Pascal also allows multiple with-variables such as "With Var1,Var2" which makes it even harder.

逆光下的微笑 2024-08-28 10:14:48
with (OBJECT) {CODE}

C++中没有这样的东西。
您可以将 CODE 按原样放入 OBJECT 的方法中,但这并不总是可取的。

使用 C++11,您可以通过为 OBJECT 创建短名称的别名来非常接近。
例如,有问题的代码看起来像这样:(

{
    auto &_ = *pointer;
    if (_.field1 && ... && _.fieldn) {...}
}

周围的大括号用于限制别名 _ 的可见性)

如果您经常使用某个字段,您可以直接为其添加别名:

auto &field = pointer->field;
// Even shorter alias:
auto &_ = pointer->busy_field;
with (OBJECT) {CODE}

There is no such thing in C++.
You can put CODE as is into a method of OBJECT, but it is not always desirable.

With C++11 you can get quite close by creating alias with short name for OBJECT.
For example code given in question it will look like so:

{
    auto &_ = *pointer;
    if (_.field1 && ... && _.fieldn) {...}
}

(The surrounding curly braces are used to limit visibility of alias _ )

If you use some field very often you can alias it directly:

auto &field = pointer->field;
// Even shorter alias:
auto &_ = pointer->busy_field;
掌心的温暖 2024-08-28 10:14:48

不,C/C++ 中没有 with 关键字。

但您可以使用一些预处理器代码添加它:

/* Copyright (C) 2018 Piotr Henryk Dabrowski, Creative Commons CC-BY 3.0 */

#define __M2(zero, a1, a2, macro, ...) macro

#define __with2(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

#define __with1(object) __with2(object, it)

#define with(...) \
    __M2(0, ##__VA_ARGS__, __with2(__VA_ARGS__), __with1(__VA_ARGS__))

用法:

with (someVeryLongObjectNameOrGetterResultOrWhatever) {
    if (it)
        it->...
    ...
}

with (someVeryLongObjectNameOrGetterResultOrWhatever, myObject) {
    if (myObject)
        myObject->...
    ...
}

简化的未重载定义(选择一个):

未命名(Kotlin 样式 it):

#define with(object) \
    for (typeof(object) &it = (object), *__i = 0; __i < (void*)1; ++__i)

命名:

#define with(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

当然 for 循环始终具有只需一次传递,并将被编译器优化掉。

No, there is no with keyword in C/C++.

But you can add it with some preprocessor code:

/* Copyright (C) 2018 Piotr Henryk Dabrowski, Creative Commons CC-BY 3.0 */

#define __M2(zero, a1, a2, macro, ...) macro

#define __with2(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

#define __with1(object) __with2(object, it)

#define with(...) \
    __M2(0, ##__VA_ARGS__, __with2(__VA_ARGS__), __with1(__VA_ARGS__))

Usage:

with (someVeryLongObjectNameOrGetterResultOrWhatever) {
    if (it)
        it->...
    ...
}

with (someVeryLongObjectNameOrGetterResultOrWhatever, myObject) {
    if (myObject)
        myObject->...
    ...
}

Simplified unoverloaded definitions (choose one):

unnamed (Kotlin style it):

#define with(object) \
    for (typeof(object) &it = (object), *__i = 0; __i < (void*)1; ++__i)

named:

#define with(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

Of course the for loop always has only a single pass and will be optimized out by the compiler.

ゞ花落谁相伴 2024-08-28 10:14:48

我第一次听说有人不喜欢“with”。这些规则非常简单,与 C++ 或 Java 中的类内部发生的情况没有什么不同。并且不要忽视它可以触发重大的编译器优化。

First I've heard that anybody doesn't like 'with'. The rules are perfectly straightforward, no different from what happens inside a class in C++ or Java. And don't overlook that it can trigger a significant compiler optimization.

你在看孤独的风景 2024-08-28 10:14:48

下面的方法依赖于Boost。如果您的编译器支持 C++0x 的 auto,那么您可以使用它并摆脱 Boost 依赖。

免责声明:请不要在任何必须由其他人(甚至几个月后由您自己)维护或阅读的代码中执行此操作:

#define WITH(src_var)                                             \
    if(int cnt_ = 1)                                              \
        for(BOOST_AUTO(const & _, src_var); cnt_; --cnt_)


int main()
{
    std::string str = "foo";

    // Multiple statement block
    WITH(str)
    {
        int i = _.length();
        std::cout << i << "\n";
    }

    // Single statement block
    WITH(str)
        std::cout << _ << "\n";

    // Nesting
    WITH(str)
    {
        std::string another("bar");
        WITH(another)
            assert(_ == "bar");
    }
}

The following approach relies on Boost. If your compiler supports C++0x's auto then you can use that and get rid of the Boost dependence.

Disclaimer: please don't do this in any code that must be maintained or read by someone else (or even by yourself in a few months):

#define WITH(src_var)                                             \
    if(int cnt_ = 1)                                              \
        for(BOOST_AUTO(const & _, src_var); cnt_; --cnt_)


int main()
{
    std::string str = "foo";

    // Multiple statement block
    WITH(str)
    {
        int i = _.length();
        std::cout << i << "\n";
    }

    // Single statement block
    WITH(str)
        std::cout << _ << "\n";

    // Nesting
    WITH(str)
    {
        std::string another("bar");
        WITH(another)
            assert(_ == "bar");
    }
}
依 靠 2024-08-28 10:14:48

编写了许多解析器后,这似乎是一个查找命名对象(静态或动态)的简单列表。此外,我从未见过编译器无法正确识别丢失的对象和类型的情况,因此所有那些不允许使用WITH ...ENDWITH 构造的蹩脚借口似乎都是胡言乱语。对于我们其他容易使用长对象名称的人来说,一种解决方法是创建简单的定义。无法抗拒,假设我有:

    #include<something> 
    typedef int headache;
    class grits{
      public:
       void corn(void);
       void cattle(void);
       void hay(void);}; //insert function defs here
     void grits::grits(void)(printf("Welcome to Farm-o-mania 2012\n");};

    #define m mylittlepiggy_from_under_the_backporch.
    headache main(){
       grits mylittlepiggy_from_under_the_backporch;
         m corn();  //works in GCC
         m cattle();
         m hay();
      return headache;

Having written numerous parsers, this seems like a dead simple list look up for the named object, either static or dynamic. Further, I have never seen a situation where the compiler did not correctly identify the missing object and type, so all those lame excuses for not allowing a WITH ...ENDWITH construction would seem to be a lot of hooey. For the rest of us prone to long object names one workaround is to create simple defines. Couldn't resist, suppose I have:

    #include<something> 
    typedef int headache;
    class grits{
      public:
       void corn(void);
       void cattle(void);
       void hay(void);}; //insert function defs here
     void grits::grits(void)(printf("Welcome to Farm-o-mania 2012\n");};

    #define m mylittlepiggy_from_under_the_backporch.
    headache main(){
       grits mylittlepiggy_from_under_the_backporch;
         m corn();  //works in GCC
         m cattle();
         m hay();
      return headache;
七秒鱼° 2024-08-28 10:14:48
#include <iostream>

using namespace std;

template <typename T>
struct with_iter {
  with_iter( T &val ) : p(&val) {}

  inline T* begin() { return p; }
  inline T* end() { return p+1; }

  T *p;
};

#define with( N, I ) for( auto &N : with_iter<decltype(I)>(I) )

int main() {

  with( out , cout ) {
    out << "Hello world!" << endl;
  }

  return 0;
}

努夫说……

#include <iostream>

using namespace std;

template <typename T>
struct with_iter {
  with_iter( T &val ) : p(&val) {}

  inline T* begin() { return p; }
  inline T* end() { return p+1; }

  T *p;
};

#define with( N, I ) for( auto &N : with_iter<decltype(I)>(I) )

int main() {

  with( out , cout ) {
    out << "Hello world!" << endl;
  }

  return 0;
}

Nuf said ...

滥情哥ㄟ 2024-08-28 10:14:48

我可以看到一个例子,其中“with”实际上很有用。

在递归数据结构的方法中,经常会遇到这样的情况:

void A::method()
{
  for (A* node = this; node; node = node->next) {
    abc(node->value1);
    def(value2); // -- oops should have been node->value2
    xyz(node->value3);
  }
}

像这样的拼写错误导致的错误很难被发现。

使用“with”,你可以写

void A::method()
{
  for (A* node = this; node; node = node->next) with (node) {
    abc(value1);
    def(value2);
    xyz(value3);
  }
}

这可能不会超过“with”提到的所有其他负面因素,但只是作为一个有趣的信息......

I can see one instance where 'with' is actually useful.

In methods for recursive data structures, you often have the case:

void A::method()
{
  for (A* node = this; node; node = node->next) {
    abc(node->value1);
    def(value2); // -- oops should have been node->value2
    xyz(node->value3);
  }
}

errors caused by typos like this are very hard to find.

With 'with' you could write

void A::method()
{
  for (A* node = this; node; node = node->next) with (node) {
    abc(value1);
    def(value2);
    xyz(value3);
  }
}

This probably doesn't outweight all the other negatives mentioned for 'with', but just as an interesting info...

丘比特射中我 2024-08-28 10:14:48

也许您可以:

auto p = *pointer;
if (p.field1) && (p.field2) && ... (p.fieldn)

或者创建一个小程序,它能够理解 C++ 中的 with 语句,并将它们转换为某种形式的有效 C++。

Maybe you can:

auto p = *pointer;
if (p.field1) && (p.field2) && ... (p.fieldn)

Or create a small program that will understand with statements in C++ and translate them to some form of a valid C++.

愛上了 2024-08-28 10:14:48

我也来自 Pascal 世界......而且我也喜欢 Python 使用 with (基本上有一个自动 try/finally):

  with open(filename, "r") as file:
    for line in file:
      if line.startswith("something"):
        do_more()

这就像一个智能 ptr 对象。如果打开失败,则不会进入该块;当离开块时,文件被关闭。

这是一个非常接近 Pascal 的示例,同时也支持 Python 的使用(假设您有一个具有析构函数清理功能的智能对象);您需要更新的 C++ 标准编译器才能工作。

    // Old way
    cxGrid_s cxGrid{};
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["foo"] = 1;
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["bar"] = 2;
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["baz"] = 3;
    // New Way - FieldByName will now be directly accessible.
    // the `;true` is only needed if the call does not return bool or pointer type
    if (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
    {
        FieldByName.fn1 = 0;
        FieldByName.fn2 = 3;
        FieldByName.value["foo"] = 1;
        FieldByName.value["bar"] = 2;
        FieldByName.value["baz"] = 3;
    }

如果您想要更接近:

    #define with if

    with (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
    // Similar to the Python example
    with (smartFile sf("c:\\file.txt"); sf)
    {
        fwrite("...", 1, 3, *sf);
    }
    // Usage with a smart pointer
    with (std::unique_ptr<class_name> p = std::make_unique<class_name>())
    {
        p->DoSomethingAmazing();

        // p will be released and cleaned up upon exiting the scope
    }

此示例的(快速而肮脏的)支持代码:

#include <map>
#include <string>
struct cxGrid_s {
    int g1, g2;
    struct DBTableView_s {
        int tv1, tv2;
        struct ViewData_s {
            int vd1, vd2;
            struct Records_s {
                int r1, r2;
                struct FieldByName_s{
                    int fn1, fn2;
                    std::map<std::string, int> value;
                } FieldByName;
            } Records;
        } ViewData;
    } DBTableView;
};

class smartFile
{
public:
    FILE* f{nullptr};
    smartFile() = delete;
    smartFile(std::string fn) { f = fopen(fn.c_str(), "w");    }
    ~smartFile()              { if (f) fclose(f); f = nullptr; }
    FILE* operator*()         { return f;            }
    FILE& operator->()        { return *f;           }
    operator bool() const     { return f != nullptr; }
};

I too came from the Pascal world..... .....and I also LOVE Python's use of with (basically having an automatic try/finally):

  with open(filename, "r") as file:
    for line in file:
      if line.startswith("something"):
        do_more()

That acts like a smart ptr object. It does not go into the block if the open failed; and when leaving the block, the file if closed.

Here is a sample very close to Pascal while also supporting Python's usage (assuming you have a smart object with destructor cleanup); You need newer C++ standard compilers for it to work.

    // Old way
    cxGrid_s cxGrid{};
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["foo"] = 1;
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["bar"] = 2;
    cxGrid.DBTableView.ViewData.Records.FieldByName.value["baz"] = 3;
    // New Way - FieldByName will now be directly accessible.
    // the `;true` is only needed if the call does not return bool or pointer type
    if (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
    {
        FieldByName.fn1 = 0;
        FieldByName.fn2 = 3;
        FieldByName.value["foo"] = 1;
        FieldByName.value["bar"] = 2;
        FieldByName.value["baz"] = 3;
    }

And if you want even closer:

    #define with if

    with (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
    // Similar to the Python example
    with (smartFile sf("c:\\file.txt"); sf)
    {
        fwrite("...", 1, 3, *sf);
    }
    // Usage with a smart pointer
    with (std::unique_ptr<class_name> p = std::make_unique<class_name>())
    {
        p->DoSomethingAmazing();

        // p will be released and cleaned up upon exiting the scope
    }

The (quick and dirty) supporting code for this example:

#include <map>
#include <string>
struct cxGrid_s {
    int g1, g2;
    struct DBTableView_s {
        int tv1, tv2;
        struct ViewData_s {
            int vd1, vd2;
            struct Records_s {
                int r1, r2;
                struct FieldByName_s{
                    int fn1, fn2;
                    std::map<std::string, int> value;
                } FieldByName;
            } Records;
        } ViewData;
    } DBTableView;
};

class smartFile
{
public:
    FILE* f{nullptr};
    smartFile() = delete;
    smartFile(std::string fn) { f = fopen(fn.c_str(), "w");    }
    ~smartFile()              { if (f) fclose(f); f = nullptr; }
    FILE* operator*()         { return f;            }
    FILE& operator->()        { return *f;           }
    operator bool() const     { return f != nullptr; }
};
人海汹涌 2024-08-28 10:14:48

我对 PotatoSwatter (当前接受的答案)感到遗憾,我无法使用该解决方案访问封闭范围中声明的变量。
我试图将其发布在对 PotatoSwatter 的评论回复中,但作为一个整体发布会更好。这一切都有点过头了,但是语法糖非常好!

#define WITH_SIG float x, float y, float z
#define WITH_ARG x, y, z

#define WITH(T,s) do { struct WITH : T { void operator()(s) {
#define ENDWITH(X,s) }}; static_cast<WITH&>((X))(s); } while(0)

class MyClass {
    Vector memberVector;
    static void myFunction(MyClass* self, WITH_SIG) {
        WITH(MyClass, WITH_SIG)
            memberVector = Vector(x,y,z);
        ENDWITH(*self, WITH_ARG);
    }
}

I was lamenting to PotatoSwatter (currently accepted answer) that I could not access variables declared in the enclosing scope with that solution.
I tried to post this in a comment response to PotatoSwatter, but it's better as a whole post. It's all a bit over the top, but the syntax sugar is pretty nice!

#define WITH_SIG float x, float y, float z
#define WITH_ARG x, y, z

#define WITH(T,s) do { struct WITH : T { void operator()(s) {
#define ENDWITH(X,s) }}; static_cast<WITH&>((X))(s); } while(0)

class MyClass {
    Vector memberVector;
    static void myFunction(MyClass* self, WITH_SIG) {
        WITH(MyClass, WITH_SIG)
            memberVector = Vector(x,y,z);
        ENDWITH(*self, WITH_ARG);
    }
}
偏闹i 2024-08-28 10:14:48

一个简单的方法如下:

class MyClass
{
    int& m_x;

    public MyClass(int& x)
    {
        m_x = x;
        m_x++;
    }

    ~MyClass()
    {
        m_x--;
    }
}
int main():
{
    x = 0;
    {
        MyClass(x)  // x == 1 whilst in this scope
    }
}

我整天都在写 python,只是在有人带我去清理之前就把它废弃了。在较大的程序中,这是如何对某些内容进行可靠计数的示例。

A simple way to do this is as follows

class MyClass
{
    int& m_x;

    public MyClass(int& x)
    {
        m_x = x;
        m_x++;
    }

    ~MyClass()
    {
        m_x--;
    }
}
int main():
{
    x = 0;
    {
        MyClass(x)  // x == 1 whilst in this scope
    }
}

I've been writing python all day long and just scrapped this down before anyone takes me to the cleaners. In a larger program this is an example of how to keep a reliable count for something.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文