跳转至

内置数据类型 基础数据类型

本文介绍基础的数据类型

IException

ICore中支持c++ exception 的机制。exception 的类声明如下:

class IException
{
public:
    IException(QString cause);
    virtual ~IException() = default;

public:
    const QString& getCause() const;

private:
    QString m_cause;
};

注意事项

exception 在使用过程中请谨慎使用,除了在以下的两种情形之外,不建议使用异常机制。

  • 在函数调用链过深,有循环调用等, 但是调用入口是明确的情况下,建议使用异常机制。这样可以在调用的入口处捕获异常,在调用中的节点随时抛出异常。比如做 html 模板解析的时候。
  • 在网络连接等外部环境变化的情况下,比如数据库查询操作。这个在正常情况下是没有问题的,如果出现问题,则通过异常更能解决问题。

其他的情况不建议使用 exception。更多关于安全的内容,请查看安全策略 的文档。

IRdbException

如果用户需要使用 IException,请不要直接使用,需要生成子类之后,使用子类这种具有更明确语义的类型。在目前的项目进展中,目前支持 IRdbException子类。这个是由于数据库操作是一个不可靠,不确定的操作。

他的使用方式如下:

template<typename T, bool enabled>
QSqlDatabase IRdbSqliteDatabaseInterface<T, enabled>::openDatatbase()
{
    QSqlDatabase database;
    database = QSqlDatabase::addDatabase(this->m_dataSource.driverName, IMetaUtil::getTypeName<T>() + "_0");
    database.setDatabaseName(this->m_dataSource.databaseName);

    if(!database.open()){
        throw IRdbException(database.lastError());  // 在创建连接的时候抛出异常
    }

    return database;
}

ISqlQuery IRdbDatabaseWare::createQuery()
{
    if(auto db = lockConnection()){
        return ISqlQuery(db, m_dialect);
    }
    throw IRdbException("fail to create query");    // 在数据库connection invalid 的时候 抛出异常。
}

在 c++ 中,抛出的异常一定要被拦截掉,不然整个程序就会崩溃掉。如上,IRdbException 抛出的异常在 Http 请求处理的过程中被拦截。如果拦截到异常,则会返回用户 500 状态。

IJson

在我们ICore中,使用nlohmann/json作为我们的 json 工具。这是由于 nlohmann/json 高性能,易用性和功能全面的优点。在ICore中,我们使用 IJson 来重命名 nlohmann/json。如下是 IJson.h 的代码

using IJson = nlohmann::json;
Q_DECLARE_METATYPE(IJson)

在第一行代码中,我们重命名了 nlohmann/json 为 IJson, 第二行代码我们将 IJson 注册为 Qt的元对象类型,使IJson 可以被反射使用。

其次 IJson 的命名习惯更符合 ICore 的命名习惯,使代码更加自然流畅。

在 ICore程序中,不再建议用户使用 nlohmann/json 类型去操作 json 数据,而是使用更加简短的 IJson 类型。

IJsonUtil

在ICore中,应对于IJson和其他数据类型相互转换的需求,定义了 IJsonUtil 的工具集,它主要包括 两类的函数 fromJson 和 toJson。

fromJson

IJsonUtil::fromJson 的声明如下:

// basic types
inline bool fromJson(bool& data, const IJson& json);
inline bool fromJson(QString& data, const IJson& json);
inline bool fromJson(std::string& data, const IJson& json);
inline bool fromJson(IString& data, const IJson& json);
inline bool fromJson(IJson& value, const IJson& json);
inline bool fromJson(QDate& value, const IJson& json);
inline bool fromJson(QTime& value, const IJson& json);
inline bool fromJson(QDateTime& value, const IJson& json);
inline bool fromJson(QStringList& value, const IJson& json);

// numbers
template <typename T>
std::enable_if_t<std::is_arithmetic_v<T>, bool>
fromJson(T& data, const IJson& json);

// beans
template<typename T>
std::enable_if_t<ITraitUtil::has_class_member_loadJson_v<T>, bool>
fromJson(T& data, const IJson& json);

// std::map
template<typename T, typename U>
bool fromJson(std::map <T, U>& data, const IJson& json);

// qmap
template<typename T, typename U>
bool fromJson(QMap <T, U>& data, const IJson& json);

// list / vector
#define PP_FROM_JSON_SEQUENCE_CONTAINER(Type)                                   \
    template<typename T>                                                        \
    bool fromJson( Type <T>& data, const IJson& json)                           \
    {                                                                           \
        if(!json.is_array()) return false;                                      \
        for(const IJson& val : json){                                           \
            T bean;                                                             \
            if(!(::IWebCore::IJsonUtil::fromJson(bean, val)))  return false;                           \
            data.push_back(std::move(bean));                                    \
        }                                                                       \
        return true;                                                            \
    }
    PP_FROM_JSON_SEQUENCE_CONTAINER(QList)
    PP_FROM_JSON_SEQUENCE_CONTAINER(QVector)
    PP_FROM_JSON_SEQUENCE_CONTAINER(std::list)
    PP_FROM_JSON_SEQUENCE_CONTAINER(std::vector)
#undef PP_FROM_JSON_SEQUENCE_CONTAINER

在上述的代码中,可以看见, fromJson 的基本签名是:

1
2
3
4
5
namespace IJsonUtil
{
    template<typename T>
    bool from Json(T&, const IJson&);
}

其中T 的类型可以为:

  • 基础类型:bool, QString, std::string, IString, IJson, QDate, QTime, QDateTime, QStringList,
  • 数值类型, 包括整型和浮点类型。
  • Bean 类型。关于该类型,请参考 Bean 相关的文档。
  • std::list, std::vector, QList, QVector 序列容器。
  • std::map, QMap, 关联容器类型。

当IJson 转换成功的时候,返回值为 true, 当不成功的时候,返回值是false。

toJson

toJson 的基本签名是:

1
2
3
4
5
namespace IJsonUtil
{
    template<typename T>
    IJson toJson(T value);
}

其中 T 的类型可以是:

  • 基础类型:bool, QString, std::string, IString, IJson, QDate, QTime, QDateTime, QStringList,
  • 数值类型, 包括整型和浮点类型。
  • Bean 类型。关于该类型,请参考 Bean 相关的文档。
  • std::list, std::vector, QList, QVector 序列容器。
  • std::map, QMap, 关联容器类型。

toJson 不会有转换不成功的情形.

IResult

IResult 是对 std::optional 的简短封装

template<typename T>
using IResult = std::optional<T>;

就是这么简单.这么做的目的是统一书写方式.

IString

IStringView

IStringViewStash