c++ - "empty"有简洁的反义词吗?

标签 c++ string containers api-design readability

字符串类的接口(interface)通常具有名为 IsEmpty ( VCL ) 或 empty ( STL ) 的方法。这是绝对合理的,因为它是一种特殊情况,但是使用这些方法的代码通常不得不否定这个谓词,这会导致“视觉上的(甚至心理上的)开销” (感叹号不是很明显,尤其是在左括号之后)。参见例如这个(简化的)代码:

/// format an optional time specification for output
std::string fmtTime(const std::string& start, const std::string& end)
{
    std::string time;
    if (!start.empty() || !end.empty()) {
        if (!start.empty() && !end.empty()) {
            time = "from "+start+" to "+end;
        } else {
            if (end.empty()) {
                time = "since "+start;
            } else {
                time = "until "+end;
            }
        }
    }
    return time;
}

它有四个否定,因为空的情况是要跳过的。我经常观察到这种否定,在设计界面时也是如此,这不是大问题,但很烦人。我只希望支持编写易于理解和易于阅读的代码。我希望你能明白我的意思。

也许我只是对盲目感到震惊:您将如何解决上述问题?


编辑: 看了一些评论,我觉得应该说原代码使用了VCL的System::AnsiString类。这个类提供了一个IsEmpty方法,可读性很强:

 if (text.IsEmpty()) { /* ... */ } // read: if text is empty ...

如果没有否定:

 if (!text.IsEmpty()) { /* ... */} // read: if not text is empty ... 

...而不是 如果文本不为空。我认为文字 is 最好留给读者的幻想,让否定也能正常工作。好吧,也许不是一个普遍的问题......

最佳答案

在大多数情况下,您可以颠倒 ifelse 的顺序来清理代码:

const std::string fmtTime(const std::string& start, const std::string& end)
{
    std::string time;
    if (start.empty() && end.empty()) {
        return time;
    }

    if (start.empty() || end.empty()) {
        if (end.empty()) {
            time = "since "+start;
        } else {
            time = "until "+end;
        }
    } else {
        time = "from "+start+" to "+end;
    }
    return time;
}

或者在一些更多的重构之后甚至更干净:

std::string fmtTime(const std::string& start, const std::string& end)
{
    if (start.empty() && end.empty()) {
        return std::string();
    }

    if (start.empty()) {
        return "until "+end;
    }    

    if (end.empty()) {
        return "since "+start;
    }

    return "from "+start+" to "+end;
}

为了最终的紧凑性(虽然我更喜欢以前的版本,因为它的可读性):

std::string fmtTime(const std::string& start, const std::string& end)
{
    return start.empty() && end.empty() ? std::string()
         : start.empty()                ? "until "+end
         :                  end.empty() ? "since "+start
                                        : "from "+start+" to "+end;
}

另一种可能性是创建一个辅助函数:

inline bool non_empty(const std::string &str) {
  return !str.empty();
}

if (non_empty(start) || non_empty(end)) {
...
}

关于c++ - "empty"有简洁的反义词吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21882655/

相关文章:

C++,模板的非参数类型 : only const variables?

Java:文件读取器、按定界符分隔的字符串分隔符帮助

docker - 1#1 : pread() "/etc/nginx/conf.d/default.conf" failed (38: Function not implemented)

C++容器类类型转换

c++ - 在循环中创建新线程是否安全?

c++ - 关于结构 vector 数组的问题

c++ - Metal - 针对内存延迟优化 GPU 矩阵乘法

python - 使用 Python 高效重复子字符串替换

C: 格式 %s 在有趣的字符串程序中需要 char* 类型的参数

kubernetes - 如何通过fluentd将json日志发送到stackdriver