Qt MetaTypeInterface

news/2024/9/19 14:10:53/文章来源:https://www.cnblogs.com/DesertCactus/p/18417800
  1. Qt中的Meta Type 包含两种类型,每个类型都以一个整型ID来表示, 内建类型和用户自定义类型(自定义类型对应的整型ID 从65536 即 QMetaType::User 开始):

1)内建类型:

corelib\kernel\qmetatype.h// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
#define QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)\F(Bool, 1, bool) \F(Int, 2, int) \F(UInt, 3, uint) \F(LongLong, 4, qlonglong) \F(ULongLong, 5, qulonglong) \F(Double, 6, double) \F(Long, 32, long) \F(Short, 33, short) \F(Char, 34, char) \F(Char16, 56, char16_t) \F(Char32, 57, char32_t) \F(ULong, 35, ulong) \F(UShort, 36, ushort) \F(UChar, 37, uchar) \F(Float, 38, float) \F(SChar, 40, signed char) \F(Nullptr, 51, std::nullptr_t) \F(QCborSimpleType, 52, QCborSimpleType) \#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)        \QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)   \F(Void, 43, void) \#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)     \F(VoidStar, 31, void*) \#if QT_CONFIG(easingcurve)
#define QT_FOR_EACH_STATIC_EASINGCURVE(F)\F(QEasingCurve, 29, QEasingCurve)
#else
#define QT_FOR_EACH_STATIC_EASINGCURVE(F)
#endif#if QT_CONFIG(itemmodel)
#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\F(QModelIndex, 42, QModelIndex) \F(QPersistentModelIndex, 50, QPersistentModelIndex)
#else
#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
#endif#if QT_CONFIG(regularexpression)
#  define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \F(QRegularExpression, 44, QRegularExpression)
#else
#  define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F)
#endif#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\F(QChar, 7, QChar) \F(QString, 10, QString) \F(QByteArray, 12, QByteArray) \F(QBitArray, 13, QBitArray) \F(QDate, 14, QDate) \F(QTime, 15, QTime) \F(QDateTime, 16, QDateTime) \F(QUrl, 17, QUrl) \F(QLocale, 18, QLocale) \F(QRect, 19, QRect) \F(QRectF, 20, QRectF) \F(QSize, 21, QSize) \F(QSizeF, 22, QSizeF) \F(QLine, 23, QLine) \F(QLineF, 24, QLineF) \F(QPoint, 25, QPoint) \F(QPointF, 26, QPointF) \QT_FOR_EACH_STATIC_EASINGCURVE(F) \F(QUuid, 30, QUuid) \F(QVariant, 41, QVariant) \QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \F(QJsonValue, 45, QJsonValue) \F(QJsonObject, 46, QJsonObject) \F(QJsonArray, 47, QJsonArray) \F(QJsonDocument, 48, QJsonDocument) \F(QCborValue, 53, QCborValue) \F(QCborArray, 54, QCborArray) \F(QCborMap, 55, QCborMap) \F(Float16, 63, qfloat16) \QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\F(QObjectStar, 39, QObject*)#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\F(QVariantMap, 8, QVariantMap) \F(QVariantList, 9, QVariantList) \F(QVariantHash, 28, QVariantHash) \F(QVariantPair, 58, QVariantPair) \F(QByteArrayList, 49, QByteArrayList) \F(QStringList, 11, QStringList) \#if QT_CONFIG(shortcut)
#define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\F(QKeySequence, 0x100b, QKeySequence)
#else
#define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)
#endif#define QT_FOR_EACH_STATIC_GUI_CLASS(F)\F(QFont, 0x1000, QFont) \F(QPixmap, 0x1001, QPixmap) \F(QBrush, 0x1002, QBrush) \F(QColor, 0x1003, QColor) \F(QPalette, 0x1004, QPalette) \F(QIcon, 0x1005, QIcon) \F(QImage, 0x1006, QImage) \F(QPolygon, 0x1007, QPolygon) \F(QRegion, 0x1008, QRegion) \F(QBitmap, 0x1009, QBitmap) \F(QCursor, 0x100a, QCursor) \QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) \F(QPen, 0x100c, QPen) \F(QTextLength, 0x100d, QTextLength) \F(QTextFormat, 0x100e, QTextFormat) \F(QTransform, 0x1010, QTransform) \F(QMatrix4x4, 0x1011, QMatrix4x4) \F(QVector2D, 0x1012, QVector2D) \F(QVector3D, 0x1013, QVector3D) \F(QVector4D, 0x1014, QVector4D) \F(QQuaternion, 0x1015, QQuaternion) \F(QPolygonF, 0x1016, QPolygonF) \F(QColorSpace, 0x1017, QColorSpace) \#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\F(QSizePolicy, 0x2000, QSizePolicy) \// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\F(ULong, -1, ulong, "unsigned long") \F(UInt, -1, uint, "unsigned int") \F(UShort, -1, ushort, "unsigned short") \F(UChar, -1, uchar, "unsigned char") \F(LongLong, -1, qlonglong, "long long") \F(ULongLong, -1, qulonglong, "unsigned long long") \F(SChar, -1, signed char, "qint8") \F(UChar, -1, uchar, "quint8") \F(Short, -1, short, "qint16") \F(UShort, -1, ushort, "quint16") \F(Int, -1, int, "qint32") \F(UInt, -1, uint, "quint32") \F(LongLong, -1, qlonglong, "qint64") \F(ULongLong, -1, qulonglong, "quint64") \F(QVariantList, -1, QVariantList, "QList<QVariant>") \F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \F(QStringList, -1, QStringList, "QList<QString>") \#define QT_FOR_EACH_STATIC_TYPE(F)\QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\QT_FOR_EACH_STATIC_CORE_CLASS(F)\QT_FOR_EACH_STATIC_CORE_POINTER(F)\QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\QT_FOR_EACH_STATIC_GUI_CLASS(F)\QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \TypeName = Id,#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \F(QList) \F(QQueue) \F(QStack) \F(QSet) \/*end*/#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \F(QHash, class) \F(QMap, class)#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \F(QSharedPointer) \F(QWeakPointer) \F(QPointer)class Q_CORE_EXPORT QMetaType {
public:
#ifndef Q_QDOC// The code that actually gets compiled.enum Type {// these are merged with QVariantQT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)FirstCoreType = Bool,LastCoreType = Float16,FirstGuiType = QFont,LastGuiType = QColorSpace,FirstWidgetsType = QSizePolicy,LastWidgetsType = QSizePolicy,HighestInternalId = LastWidgetsType,QReal = sizeof(qreal) == sizeof(double) ? Double : Float,UnknownType = 0,User = 65536};
#else// If we are using QDoc it fakes the Type enum looks like this.enum Type {UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,UChar = 37, Float = 38,VoidStar = 31,QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26,QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,QPersistentModelIndex = 50, QRegularExpression = 44,QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,QByteArrayList = 49, QObjectStar = 39, SChar = 40,Void = 43,Nullptr = 51,QVariantMap = 8, QVariantList = 9, QVariantHash = 28, QVariantPair = 58,QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,Char16 = 56, Char32 = 57,Int128 = 59, UInt128 = 60, Float128 = 61, BFloat16 = 62, Float16 = 63,// Gui typesQFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004,QIcon = 0x1005, QImage = 0x1006, QPolygon = 0x1007, QRegion = 0x1008, QBitmap = 0x1009,QCursor = 0x100a, QKeySequence = 0x100b, QPen = 0x100c, QTextLength = 0x100d, QTextFormat = 0x100e,QTransform = 0x1010, QMatrix4x4 = 0x1011, QVector2D = 0x1012,QVector3D = 0x1013, QVector4D = 0x1014, QQuaternion = 0x1015, QPolygonF = 0x1016, QColorSpace = 0x1017,// Widget typesQSizePolicy = 0x2000,// Start-point for client-code types:User = 65536};

2)自定义类型,需要向customRegistry中注册用户自定义类型信息:

#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                         \QT_WARNING_PUSH                                                         \QT_WARNING_DISABLE_CLANG("-Wunevaluated-expression")                    \namespace { struct Q_QGS_ ## NAME {                                     \typedef TYPE QGS_Type;                                              \static void innerFunction(void *pointer)                            \noexcept(noexcept(std::remove_cv_t<QGS_Type> ARGS))             \{                                                                   \new (pointer) QGS_Type ARGS;                                    \}                                                                   \}; }                                                                    \Q_CONSTINIT static QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_ ## NAME>> NAME; \QT_WARNING_POP/**/#define Q_GLOBAL_STATIC(TYPE, NAME, ...)                                    \Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, (__VA_ARGS__))Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)宏定义替换后会得到一个静态全局变量 customTypeRegistry的声明,类型为QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_customTypeRegistry >>, 替换后的代码如下:namespace 
{ struct Q_QGS_customTypeRegistry{                                     typedef TYPE QMetaTypeCustomRegistry;   static void innerFunction(void *pointer) noexcept(noexcept(QMetaTypeCustomRegistry ()))            {                                                                   new (pointer) QMetaTypeCustomRegistry() ;                                   }   }; 
}Q_CONSTINIT static QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_customTypeRegistry >> customTypeRegistry; 在QMetaTypeCustomRegistry类中提供了注册自定义类型的接口:
struct QMetaTypeCustomRegistry
{#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)QMetaTypeCustomRegistry(){/* qfloat16 was neither a builtin, nor unconditionally registeredin QtCore in Qt <= 6.2.Inserting it as an alias ensures that a QMetaType::id callwill get the correct built-in type-id (the interface pointersmight still not match, but we already deal with that case.*/aliases.insert("qfloat16", QtPrivate::qMetaTypeInterfaceForType<qfloat16>());}
#endifQReadWriteLock lock;QList<const QtPrivate::QMetaTypeInterface *> registry;QHash<QByteArray, const QtPrivate::QMetaTypeInterface *> aliases;// index of first empty (unregistered) type in registry, if any.int firstEmpty = 0;int registerCustomType(const QtPrivate::QMetaTypeInterface *cti){// we got here because cti->typeId is 0, so this is a custom meta type// (not read-only)auto ti = const_cast<QtPrivate::QMetaTypeInterface *>(cti);{QWriteLocker l(&lock);if (int id = ti->typeId.loadRelaxed())return id;QByteArray name =
#ifndef QT_NO_QOBJECTQMetaObject::normalizedType
#endif(ti->name);if (auto ti2 = aliases.value(name)) {const auto id = ti2->typeId.loadRelaxed();ti->typeId.storeRelaxed(id);return id;}aliases[name] = ti;int size = registry.size();while (firstEmpty < size && registry[firstEmpty])++firstEmpty;if (firstEmpty < size) {registry[firstEmpty] = ti;++firstEmpty;} else {registry.append(ti);firstEmpty = registry.size();}ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);}if (ti->legacyRegisterOp)ti->legacyRegisterOp();return ti->typeId.loadRelaxed();};.........
.........
.........
};
  1. 在信号槽机制中,如果使用QueuedConnection连接类型,当信号和槽中使用了自定义数据类型传递参数时需要首先注册自定义数据类型,如:
    qRegisterMetaType("Add");

至于为何需要注册自定义类型,个人理解理由如下:

在QueuedConnection 连接方式下 信号触发时 并非 对 槽函数的同步调用,而是封装一个QMetaCallEvent 以post方式放到连接队列中 等待后续EventLoop循环中对取对应的Event处理。信号函数调用结束后 栈帧已经销毁,无法在后续的Eventloop 循环中从栈中拿到对应的参数数据。
因此,比较自然的方法就是将要传递的函数参数保存在 堆上,这样不会随信号函数调用的结束而丢失要传递的参数。保存在堆上的参数内存地址 存放在上述的MetaCallEvent对象中,这样在后续循环中执行槽函数时可以获取到需要的函数参数数据。
又由于Qt 针对信号槽机制中传递参数为了更通用,因此创建链接的内部框架代码中  参数都是以 void* 类型来声明的。因此在传递给Qt框架源码时都将 用户的数据强制转换为了 void*。例如如下代码所示:

由于传递进去的是void* 类型的参数,因此要将 该参数 拷贝到 堆上保存,这时就需要知道要拷贝多少个字节。为了需要这个字节大小信息 ,因此需要有个地方记录,而记录字节大小的信息就以QMetaType的形式存放在customTypeRegistry中。Qt框架中记录了信号和槽函数中参数个数,参数类型信息。在使用自定义数据类型前先注册,注册时会在注册表中给这个新的用户自定义类型信息分配一个 整型ID,同时会根据该数据类型是否是 non-trival class 为其声明和定义copyCtr,moveCtr,等拷贝构造,移动构造信息。如下代码:

template<typename T>
struct QMetaTypeInterfaceWrapper
{// if the type ID for T is known at compile-time, then we can declare// the QMetaTypeInterface object const; otherwise, we declare it as// non-const and the .typeId is updated by QMetaType::idHelper().static constexpr bool IsConstMetaTypeInterface = !!BuiltinMetaType<T>::value;using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;static inline InterfaceType metaType = {/*.revision=*/ QMetaTypeInterface::CurrentRevision,/*.alignment=*/ alignof(T),/*.size=*/ sizeof(T),/*.flags=*/ QMetaTypeForType<T>::Flags,/*.typeId=*/ BuiltinMetaType<T>::value,/*.metaObjectFn=*/ MetaObjectForType<T>::metaObjectFunction,/*.name=*/ QMetaTypeForType<T>::getName(),/*.defaultCtr=*/ QMetaTypeForType<T>::getDefaultCtr(),/*.copyCtr=*/ QMetaTypeForType<T>::getCopyCtr(),/*.moveCtr=*/ QMetaTypeForType<T>::getMoveCtr(),/*.dtor=*/ QMetaTypeForType<T>::getDtor(),/*.equals=*/ QEqualityOperatorForType<T>::equals,/*.lessThan=*/ QLessThanOperatorForType<T>::lessThan,/*.debugStream=*/ QDebugStreamOperatorForType<T>::debugStream,/*.dataStreamOut=*/ QDataStreamOperatorForType<T>::dataStreamOut,/*.dataStreamIn=*/ QDataStreamOperatorForType<T>::dataStreamIn,/*.legacyRegisterOp=*/ QMetaTypeForType<T>::getLegacyRegister()};
};template<typename S>
class QMetaTypeForType
{
public:static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>();static constexpr unsigned Flags = QMetaTypeTypeFlags<S>::Flags;static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr(){if constexpr (std::is_default_constructible_v<S> && !QTypeInfo<S>::isValueInitializationBitwiseZero) {return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); };} else {return nullptr;}}static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr(){if constexpr (std::is_copy_constructible_v<S> && !std::is_trivially_copy_constructible_v<S>) {return [](const QMetaTypeInterface *, void *addr, const void *other) {new (addr) S(*reinterpret_cast<const S *>(other));};} else {return nullptr;}}static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr(){if constexpr (std::is_move_constructible_v<S> && !std::is_trivially_move_constructible_v<S>) {return [](const QMetaTypeInterface *, void *addr, void *other) {new (addr) S(std::move(*reinterpret_cast<S *>(other)));};} else {return nullptr;}}static constexpr QMetaTypeInterface::DtorFn getDtor(){if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)return [](const QMetaTypeInterface *, void *addr) {reinterpret_cast<S *>(addr)->~S();};elsereturn nullptr;}
}
===========================================================
C++ trivial和non-trivial构造函数及POD类型今天看书看到侯捷的《STL源码剖析》里提到trivial和non-trivial及POD类型,查了些资料理解了一下。trivial意思是无意义,这个trivial和non-trivial是对类的四种函数来说的:构造函数(ctor)
复制构造函数(copy)
赋值函数(assignment)
析构函数(dtor)
如果至少满足下面3条里的一条:显式(explict)定义了这四种函数。
类里有非静态非POD的数据成员。
有基类。
那么上面的四种函数是non-trivial函数,比如叫non-trivial ctor、non-trivial copy…,也就是说有意义的函数,里面有一下必要的操作,比如类成员的初始化,释放内存等。那个POD意思是Plain Old Data,也就是C++的内建类型或传统的C结构体类型。POD类型必然有trivial ctor/dtor/copy/assignment四种函数。//整个T是POD类型
class T
{//没有显式定义ctor/dtor/copy/assignemt所以都是trivialint a; //POD类型
};//整个T1是非POD类型
class T1
{T1() //显式定义了构造函数,所以是non-trivial ctor{}//没有显式定义ctor/dtor/copy/assignemt所以都是trivialint a;//POD类型std::string b; //非POD类型
};
那这有什么用处呢?如果这个类都是trivial ctor/dtor/copy/assignment函数,我们对这个类进行构造、析构、拷贝和赋值时可以采用最有效率的方法,不调用无所事事正真的那些ctor/dtor等,而直接采用内存操作如malloc()、memcpy()等提高性能,这也是SGI STL内部干的事情。比如STL的copy算法最基本的想法是这样的:// 非POD重载指针数值
template <class T> void copy(T* source, T* destination, int n, __false_type)
{// 省略异常处理for (; n > 0; n--,source++,destination++){// 调用source的复制构造函数constructor(source, *destination);}
}// POD重载指针数值
template <class T> void copy(T* source, T* destination, int n, __false_type)
{// 省略异常处理memmove(source, destination, n);
}
当然实际的copy比这个复杂多了,有非常多的特化等,这个只是其中一方面而已。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/798896.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Marvelous Designer基础操作3 - 贴图导出

Marvelous Designer基础操作,包括加材质、贴图,导出衣服,导入模特做适配。--本篇导航--加材质 外部贴图 导出衣服、导入到Blender 导入自己的虚拟模特 给虚拟模特加安排板 自动适配板片配合视频看材质和导出的部分 视频中还包含了做双层的方法,也就是【克隆层(外部)】【克…

自动化测试 RobotFramework自定义静态测试类库总结

实践环境 win11 家庭中文版 Python 3.9.13 robotframework6.1.1 说明:为了方便的使用robot命令,安装好robotframwork后,修改系统环境,添加robot.exe(PYTHON_HOME/Scripts/robot.exe)所在路径到系统环境变量path 安装参考连接:https://github.com/robotframework/robotfr…

Marvelous Designer基础操作2 - 制板编辑

Marvelous Designer基础操作,本篇涉及到具体的板片编辑、合并、分割、扩展等等,也包含添加洞、做省、加纽扣、拉链、明线等。​--本篇导航--板片绘制、编辑 缝线 省 内部线、打洞、做褶皱 折叠安排、假缝 扣子 拉链 明线操作可以配合这个视频看一下,注意快捷键。基础操作 双…

图解软件开发的八大模型

图解软件开发的八大模型

[rCore学习笔记 027]地址空间

写在前面 本随笔是非常菜的菜鸡写的。如有问题请及时提出。 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 引言 兜兜转转又是新的一章的开始,还是首先要看官方手册里的理论介绍和内容. 这里主要还是提纲挈领地摘抄里面的部分内容,在下面…

如何查找 18 个月之前的 Apple 订单 All In One

如何查找 18 个月之前的 Apple 订单 All In One 为什么 Apple Store 不支持查找 18 个月之前的订单?如何查找 18 个月之前的 Apple 订单 All In One为什么 Apple Store 不支持查找 18 个月之前的订单?errorssolutionsemail history ✅demos(🐞 反爬虫测试!打击盗版⚠️)…

编程日记 更改redis存储默认序列化器

编程日记 更改redis存储默认序列化器 package com.haole.usercenter.service;import com.haole.usercenter.model.domain.User; import jakarta.annotation.Resource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframewor…

结对对对项目

结对对对项目这个作业属于哪个课程 软件工程课程这个作业要求在哪里 个人项目 - 作业 - 计科22级34班 - 班级博客 - 博客园 (cnblogs.com)这个作业的目标 按照要求写一个四则运算生成器成员一 3122004883许億驰任务列表1. 实现命令行程序:创建一个命令行程序,能够生成小学四则…

闯关提交02

任务:Python实现wordcount1 import re2 from collections import defaultdict3 4 def wordcount(text):5 # 将文本转换为小写6 text = text.lower()7 8 # 使用正则表达式分割单词9 words = re.findall(r\b\w+\b, text) 10 11 # 使用 defaultdict…

M:接口耗时很短,页面数据回显慢?

1、页面卡顿,需要好长一段时间才能加载完成,可能是资源请求过多,再加上请求响应慢的原因。 每个浏览器都有资源请求并发数的限制,如何查看请求阻塞情况 到前端如何针对该限制进行优化? 先看问题: 1、设置服务端请求耗时(3S)客户端并发调用20个请求。(预留问题-见下方:…

中秋 -2024/9/17

今天是中秋假期最后一天,今天主要学习了动态规划算法,写了几个模板题 新算法学了迪杰斯特拉(Dijkstra)算法,只是过程了解了过程,还是不能用代码描述出来 寻找最短路径的算法

干盛辉的第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 介绍自己并进行评估,阐明自己的技能、薄弱点,表明期望的课程收获以及课程实践角色扮演姓名-学号 干盛辉-2022329301011一、自我介绍 (1)个人信息 大家好,我叫干盛辉,来自于浙江温州,是 22…