C++ Qt開發:使用關聯容器類

来源:https://www.cnblogs.com/LyShark/archive/2023/12/10/17891319.html
-Advertisement-
Play Games

當我們談論編程中的數據結構時,順序容器是不可忽視的一個重要概念。順序容器是一種能夠按照元素添加的順序來存儲和檢索數據的數據結構。它們提供了簡單而直觀的方式來組織和管理數據,為程式員提供了靈活性和性能的平衡。Qt 中提供了豐富的容器類,用於方便地管理和操作數據。這些容器類涵蓋了各種不同的用途,從簡單的... ...


當我們談論編程中的數據結構時,順序容器是不可忽視的一個重要概念。順序容器是一種能夠按照元素添加的順序來存儲和檢索數據的數據結構。它們提供了簡單而直觀的方式來組織和管理數據,為程式員提供了靈活性和性能的平衡。

Qt 中提供了豐富的容器類,用於方便地管理和操作數據。這些容器類涵蓋了各種不同的用途,從簡單的動態數組到複雜的映射和集合。本章我們將主要學習關聯容器,主要包括 QMapQSetQHash,它們提供了鍵值對存儲和檢索的功能,允許通過鍵來快速查找值。

1.1 QMap

QMap 是 Qt 中的有序關聯容器,用於存儲鍵值對,並按鍵的升序進行排序。以下是關於 QMap 的概述:

1.1.1 特點和用途

  • 有序性: QMap 中的元素是有序的,按照鍵的升序進行排列。
  • 唯一鍵: 每個鍵在 QMap 中是唯一的,不允許重覆鍵。
  • 鍵值對存儲: 存儲鍵值對,每個鍵關聯一個值。
  • 性能: 插入和查找操作的平均複雜度是 O(log n),適用於需要按鍵排序併進行頻繁查找的場景。

1.1.2 函數和功能

以下是關於 QMap 常用函數及其功能的總結:

函數 功能
insert(const Key &key, const T &value) QMap 中插入鍵值對。
insertMulti(const Key &key, const T &value) QMap 中插入允許相同鍵的多個值。
remove(const Key &key) 移除指定鍵的元素。
value(const Key &key) const 返回指定鍵的值。
contains(const Key &key) const 判斷是否包含指定鍵。
isEmpty() const 判斷 QMap 是否為空。
size() const 返回 QMap 中鍵值對的數量。
clear() 清空 QMap 中的所有元素。
keys() const 返回 QMap 中所有鍵的列表。
values() const 返回 QMap 中所有值的列表。
begin() 返回指向 QMap 開始位置的迭代器。
end() 返回指向 QMap 結束位置的迭代器。
constBegin() const 返回指向 QMap 開始位置的常量迭代器。
constEnd() const 返回指向 QMap 結束位置的常量迭代器。
find(const Key &key) const 返回指向 QMap 中指定鍵的迭代器。
lowerBound(const Key &key) const 返回指向 QMap 中不小於指定鍵的第一個元素的迭代器。
upperBound(const Key &key) const 返回指向 QMap 中大於指定鍵的第一個元素的迭代器。
count(const Key &key) const 返回指定鍵的數量。
toStdMap() const QMap 轉換為 std::map

這些函數提供了對 QMap 中鍵值對的插入、刪除、查找和遍歷等操作。根據需求選擇適當的函數以滿足操作要求。

1.1.3 應用案例

正如如下代碼所示,我們提供了QMap<QString,QString>字典類型的關聯數組,該數組中一個鍵映射對應一個值,QMap容器是按照順序存儲的,如果項目中不在意順序可以使用QHash容器,使用QHash效率更高些。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QMap>
#include <QMapIterator>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,QString> map;

    map["1001"] = "admin";
    map["1002"] = "guest";
    map.insert("1003","lyshark");
    map.insert("1004","lucy");
    // map.remove("1002");

    // 根據鍵值對查詢屬性
    std::cout << map["1002"].toStdString().data() << std::endl;
    std::cout << map.value("1003").toStdString().data() << std::endl;
    std::cout << map.key("admin").toStdString().data() << std::endl;

    // 使用STL語法迭代枚舉Map鍵值對
    QMap<QString,QString>::const_iterator x;
    for(x=map.constBegin();x != map.constEnd(); ++x)
    {
        std::cout << x.key().toStdString().data() << " : ";
        std::cout << x.value().toStdString().data() << std::endl;
    }

    // 使用STL語法實現修改鍵值對
    QMap<QString,QString>::iterator write_x;
    write_x = map.find("1003");
    if(write_x !=map.end())
        write_x.value()= "you ary in";

    // 使用QTglobal中自帶的foreach遍歷鍵值對
    QString each;

    // --> 單迴圈遍歷
    foreach(const QString &each,map.keys())
    {
        std::cout << map.value(each).toStdString().data() << std::endl;
    }

    // --> 多迴圈遍歷
    foreach(const QString &each,map.uniqueKeys())
    {
        foreach(QString x,map.value(each))
        {
            std::cout << each.toStdString().data() << " : ";
            std::cout << x.toStdString().data() << std::endl;
        }
    }

    return a.exec();
}

上述代碼是如何使用QMap容器,其實還有一個QMultiMap容器,該容器其實是QMap的一個子集,用於處理多值映射的類,也就是說傳統QMap只能是一對一的關係,而QMultiMap則可以實現一個Key對應多個Value或者是反過來亦可,實現一對多的關係。

如果總結起來可以發現兩者的異同點;

QMap

  • 唯一鍵: QMap 中每個鍵都是唯一的,不允許重覆鍵。
  • 鍵排序: QMap 中的元素是按鍵的升序排列的。
  • 使用場景: 適用於需要鍵值對有序且鍵唯一的場景。

QMultiMap

  • 允許重覆鍵: QMultiMap 中可以包含重覆的鍵,即多個鍵可以映射到相同的值。
  • 鍵排序: QMultiMap 中的元素是按鍵的升序排列的。
  • 使用場景: 適用於允許鍵重覆,並且需要鍵值對有序的場景。

相同點

  1. 鍵值對: 都是用於存儲鍵值對的容器。
  2. 有序性: 元素在容器中是有序的,按鍵的升序排列。

不同點

  1. 鍵唯一性: QMap 中每個鍵都是唯一的,而 QMultiMap 允許重覆的鍵。
  2. 使用場景: QMap 適用於需要鍵唯一的情況,而 QMultiMap 適用於允許鍵重覆的情況。

如下所示,展示瞭如何使用QMultiMap實現一對多的映射關係;

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QList>
#include <QMultiMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMultiMap<QString,QString> mapA,mapB,mapC,mapD;

    mapA.insert("lyshark","1000");
    mapA.insert("lyshark","2000");
    mapB.insert("admin","3000");
    mapB.insert("admin","4000");
    mapC.insert("admin","5000");

    // 獲取到裡面的所有key=lyshark的值
    QList<QString> ref;

    ref = mapA.values("lyshark");
    for(int x=0;x<ref.size();++x)
    {
        std::cout << ref.at(x).toStdString().data() << std::endl;
    }

    // 兩個key相同可相加後輸出
    mapD = mapB + mapC;

    ref = mapD.values("admin");
    for(int x=0;x<ref.size();x++)
    {
        std::cout << ref.at(x).toStdString().data() << std::endl;
    }

    return a.exec();
}

1.2 QHash

QHash 是一個無序的關聯容器,它存儲鍵值對,但與 QMap 不同,QHash 不會對鍵進行排序。

1.2.1 特點和用途

  • 鍵值對存儲: QHash 中的元素以鍵值對的形式存儲,但與 QMap 不同,QHash 中的元素是無序的。

  • 無序性: QHash 中的元素是無序的,沒有特定的排列順序。

  • 唯一鍵: 每個鍵在 QHash 中是唯一的,不允許重覆鍵。

  • 性能: 插入和查找操作的平均複雜度是 O(1),適用於需要快速插入和查找的場景。

1.2.2 函數和功能

以下是關於 QHash 常用函數及其功能的總結:

函數 功能
insert(const Key &key, const T &value) QHash 中插入鍵值對。
insertMulti(const Key &key, const T &value) QHash 中插入允許相同鍵的多個值。
remove(const Key &key) 移除指定鍵的元素。
value(const Key &key) const 返回指定鍵的值。
contains(const Key &key) const 判斷是否包含指定鍵。
isEmpty() const 判斷 QHash 是否為空。
size() const 返回 QHash 中鍵值對的數量。
clear() 清空 QHash 中的所有元素。
keys() const 返回 QHash 中所有鍵的列表。
values() const 返回 QHash 中所有值的列表。
begin() 返回指向 QHash 開始位置的迭代器。
end() 返回指向 QHash 結束位置的迭代器。
constBegin() const 返回指向 QHash 開始位置的常量迭代器。
constEnd() const 返回指向 QHash 結束位置的常量迭代器。
find(const Key &key) const 返回指向 QHash 中指定鍵的迭代器。
count(const Key &key) const 返回指定鍵的數量。
unite(const QHash &other) 合併兩個 QHash,將 other 中的元素合併到當前 QHash
intersect(const QHash &other) 保留兩個 QHash 中共有的元素,刪除其他元素。
subtract(const QHash &other) 從當前 QHash 中移除與 other 共有的元素。
toStdHash() const QHash 轉換為 std::unordered_map

這些函數提供了對 QHash 中鍵值對的插入、刪除、查找和遍歷等操作。根據需求選擇適當的函數以滿足操作要求。

1.2.3 應用案例

QHashQMap其實是一樣的,如果不需要對鍵值對進行排序那麼使用QHash將會得到更高的效率,正是因為Hash的無序,才讓其具備了更加高效的處理能力。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QHash>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QHash<QString, QString> hash;

    hash["1001"] = "admin";
    hash["1002"] = "guest";
    hash.insert("1003", "lyshark");
    hash.insert("1004", "lucy");
    // hash.remove("1002");

    // 根據鍵值對查詢屬性
    std::cout << hash["1002"].toStdString().data() << std::endl;
    std::cout << hash.value("1003").toStdString().data() << std::endl;
    std::cout << hash.key("admin").toStdString().data() << std::endl;

    // 使用STL語法迭代枚舉Hash鍵值對
    QHash<QString, QString>::const_iterator x;
    for (x = hash.constBegin(); x != hash.constEnd(); ++x)
    {
        std::cout << x.key().toStdString().data() << " : ";
        std::cout << x.value().toStdString().data() << std::endl;
    }

    // 使用STL語法實現修改鍵值對
    QHash<QString, QString>::iterator write_x;
    write_x = hash.find("1003");
    if (write_x != hash.end())
        write_x.value() = "you are in";

    // 使用Qt中自帶的foreach遍歷鍵值對
    QString each;

    // --> 單迴圈遍歷
    foreach (const QString &each, hash.keys())
    {
        std::cout << hash.value(each).toStdString().data() << std::endl;
    }

    // --> 多迴圈遍歷
    foreach (const QString &each, hash.uniqueKeys())
    {
        foreach (QString x, hash.values(each))
        {
            std::cout << each.toStdString().data() << " : ";
            std::cout << x.toStdString().data() << std::endl;
        }
    }

    return a.exec();
}

這裡需要說明一點,與QMap一樣,QHash也能夠使用QMultiHash其操作上與QMultiMap保持一致,此處讀者可自行嘗試。

1.3 QSet

QSet 是 Qt 中的無序關聯容器,類似於 C++ 標準庫的 std::unordered_set。它主要用於存儲唯一值,而不關心元素的順序。以下是關於 QSet 的概述:

1.3.1 特點和用途

  • 無序性: QSet 中的元素是無序的,沒有特定的排列順序。
  • 唯一值: 每個值在 QSet 中是唯一的,不允許重覆值。
  • 性能: 適用於需要快速查找和檢索唯一值的場景,性能比有序容器(如 QMap)更高。
  • 底層實現: 使用哈希表實現,因此插入和查找操作的平均複雜度是 O(1)。

1.3.2 函數和功能

以下是關於 QSet 常用函數及其功能的總結:

函數 功能
insert(const T &value) QSet 中插入元素。
contains(const T &value) const 判斷是否包含指定元素。
remove(const T &value) 移除指定元素。
isEmpty() const 判斷 QSet 是否為空。
size() const 返回 QSet 中元素的數量。
clear() 清空 QSet 中的所有元素。
unite(const QSet &other) 合併兩個 QSet,將 other 中的元素合併到當前 QSet
intersect(const QSet &other) 保留兩個 QSet 中共有的元素,刪除其他元素。
subtract(const QSet &other) 從當前 QSet 中移除與 other 共有的元素。
begin() 返回指向 QSet 開始位置的迭代器。
end() 返回指向 QSet 結束位置的迭代器。
constBegin() const 返回指向 QSet 開始位置的常量迭代器。
constEnd() const 返回指向 QSet 結束位置的常量迭代器。

這些函數提供了對 QSet 中元素的插入、刪除、查找和遍歷等操作。QSet 是一個無序容器,用於存儲唯一的元素。根據需求選擇適當的函數以滿足操作要求。

1.3.3 應用案例

QSet 集合容器,是基於散列表(哈希表)的集合模板,存儲順序同樣不定,查找速度最快,其內部使用QHash實現。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QSet>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QSet<QString> set;

    set << "dog" << "cat" << "tiger";

    // 測試某值是否包含於集合
    if(set.contains("cat"))
    {
        std::cout << "include" << std::endl;
    }

    return a.exec();
}

1.4 嵌套案例總結

1.4.1 QList與QMap組合

代碼通過結合使用 QListQMap 實現了數據的嵌套存儲。具體而言,通過在 QMap 中存儲鍵值對,其中鍵是時間字元串,而值是包含浮點數數據的 QList。這種結構使得可以方便地按時間檢索相關聯的數據集。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,QList<float>> map;
    QList<float> ptr;

    // 指定第一組數據
    ptr.append(10.1);
    ptr.append(12.5);
    ptr.append(22.3);
    map["10:10"] = ptr;

    // 指定第二組數據
    ptr.clear();
    ptr.append(102.2);
    ptr.append(203.2);
    ptr.append(102.1);
    map["11:20"] = ptr;

    // 輸出所有的數據
    QList<float> tmp;
    foreach(QString each,map.uniqueKeys())
    {
        tmp = map.value(each);
        std::cout << "Time: " << each.toStdString().data() << std::endl;
        for(qint32 x=0;x<tmp.count();x++)
        {
            std::cout << tmp[x]<< std::endl;
        }
    }

    return a.exec();
}

在示例中,兩組數據分別對應不同的時間鍵,每組數據存儲在相應的 QList 中。最後,通過迭代輸出了所有數據,以時間為鍵檢索相應的數據集,並將每個數據集中的浮點數逐個輸出。整體而言,這種數據結構的嵌套使用有助於組織和檢索多維度的數據。

1.4.2 QList合併為QMap

通過使用 QList 存儲頭部信息(Header)和相應的數值信息(Values),然後通過迴圈迭代將兩個列表合併為一個 QMap。在這個 QMap 中,頭部信息作為鍵,而數值作為相應的值,形成了一個鍵值對應的字典結構。最後,通過 QMap 的鍵值對操作,輸出了特定字典中的數據。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<QString> Header = {"MemTotal","MemFree","Cached","SwapTotal","SwapFree"};
    QList<float> Values = {12.5,46.8,68,100.3,55.9};
    QMap<QString,float> map;

    // 將列表合併為一個字典
    for(int x=0;x<Header.count();x++)
    {
        QString head = Header[x].toStdString().data();
        float val = Values[x];
        map[head] = val;
    }

    // 輸出特定字典中的數據
    std::cout << map.key(100.3).toStdString().data() << std::endl;
    std::cout << map.value("SwapTotal") << std::endl;

    return a.exec();
}

整體而言,這樣的數據結構使得能夠更方便地按照特定的頭部信息檢索相應的數值。

1.4.3 QMap拆分為QList

這段代碼演示瞭如何使用 QMap 存儲鍵值對,並分別將鍵和值存儲到兩個 QList 中。首先,通過 Display 函數輸出了 QMap 中的鍵值對。

接著,通過 map.keys()map.values() 分別獲取 QMap 中的所有鍵和值,將它們存儲到兩個 QList 中,並使用迴圈分別輸出了這兩個列表的內容。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

void Display(QMap<QString,float> map)
{
    foreach(const QString &each,map.uniqueKeys())
    {
        std::cout << each.toStdString().data() << std::endl;
        std::cout << map.value(each) << std::endl;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,float> map;

    map["MemTotal"] = 12.5;
    map["MemFree"] = 32.1;
    map["Cached"] = 19.2;

    Display(map);

    QList<QString> map_key;
    QList<float> map_value;

    // 分別存儲起來
    map_key = map.keys();
    map_value = map.values();

    // 輸出所有的key值
    for(int x=0;x<map_key.count();x++)
    {
        std::cout << map_key[x].toStdString().data() << std::endl;
    }

    // 輸出所有的value值
    for(int x=0;x<map_value.count();x++)
    {
        std::cout << map_value[x] << std::endl;
    }

    return a.exec();
}

1.4.4 QList結構體排序

實現對包含結構體 MyStructQList 進行排序,並輸出排序後的結果。首先,定義了一個包含整數的 QList,通過 std::sort 函數按從大到小的順序對該列表進行排序,並使用 Display 函數輸出排序後的結果。

其次,定義結構體 MyStruct,其中包含兩個成員變數 uuiduname。創建一個存儲該結構體的 QList,並添加了幾個結構體對象。通過 devListSort 函數,以結構體的 uuid 成員進行排序,並使用迴圈輸出排序後的結果。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>

struct MyStruct
{
    int uuid;
    QString uname;
};

void Display(QList<int> ptr)
{
    foreach(const int &each,ptr)
        std::cout << each << " ";
    std::cout << std::endl;
}

// 由大到小排列
int compare(const int &infoA,const int &infoB)
{
    return infoA > infoB;
}

// 針對結構體的排序方法
void devListSort(QList<MyStruct> *list)
{
    std::sort(list->begin(),list->end(),[](const MyStruct &infoA,const MyStruct &infoB)
    {
        return infoA.uuid < infoB.uuid;
    });
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 定義並對單一數組排序
    QList<int> list = {56,88,34,61,79,82,34,67,88,1};
    std::sort(list.begin(),list.end(),compare);
    Display(list);

    // 定義並對結構體排序
    QList<MyStruct> list_struct;
    MyStruct ptr;

    ptr.uuid=1005;
    ptr.uname="admin";
    list_struct.append(ptr);

    ptr.uuid=1002;
    ptr.uname = "guest";
    list_struct.append(ptr);

    ptr.uuid = 1000;
    ptr.uname = "lyshark";
    list_struct.append(ptr);

    devListSort(&list_struct);

    for(int x=0;x< list_struct.count();x++)
    {
        std::cout << list_struct[x].uuid << " ---> ";
        std::cout << list_struct[x].uname.toStdString().data() << std::endl;
    }

    return a.exec();
}

上述這段代碼演示瞭如何對一個包含整數的列表和一個包含結構體的列表進行排序,並輸出排序後的結果。在結構體排序的情況下,使用了自定義的排序方法 devListSort,該方法按照結構體的 uuid 成員進行升序排序。

文章出處:https://www.cnblogs.com/LyShark/p/17891319.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 是什麼 吹哨人巡查監控後臺master主機是否故障,如果故障了根據投票數自動將某一個從庫轉為新主庫,繼續對外服務 能幹嘛 主從監控:監控主從Redis庫運行是否正常 消息通知:哨兵可以將故障轉移的結果發送給客戶端 故障轉移:如果Master異常,則會進行主從切換,將其中一個Slave作為新Maste ...
  • 項目描述 半年前本蒻蒟在逛開源硬體平臺的時候發現了一個好玩的電子神之眼,於是開始了長達半年的製作(鴿)過程..... 本項目復刻了薩納蘭的黃昏大佬改版的神之眼S3“Pro”版核心板V1 本項目基於Arduino IDE環境 本項目硬體和軟體部分基於GPL3.0開源許可開源(可修改,可分享,可商用,但 ...
  • spring Boot應用啟動器基本的一共有44種,具體如下 1)spring-boot-starter 這是Spring Boot的核心啟動器,包含了自動配置、日誌和YAML。 2)spring-boot-starter-actuator 幫助監控和管理應用。 3)spring-boot-star ...
  • python原生數據類型有int、float、str、tuple、list、set、dict七類,本次隨筆介紹了幾種類型的定義,同時用實驗驗證各數據類型之間的嵌套,以實驗結果證明各個數據類型的基本特征。 ...
  • 本文首發於公眾號:Hunter後端 原文鏈接:Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負載均衡操作 這一篇筆記介紹如何使用 Nginx + uWSGI 來部署 Django。 上一篇筆記中有介紹直接使用 uWSGI 作為 web 伺服器來部署 Django,這一篇 ...
  • 本文是我從業多年開發生涯中針對線上業務的處理經驗總結而來,這些業務或多或少相信大家都遇到過,因此在這裡分享給大家,大家也可以看看是不是遇到過類似場景。本文大綱如下, 後臺上傳文件 線上後臺項目有一個消息推送的功能,運營新建一條通知消息時,需要一起上傳一列包含用戶 id 的文件,來給文件中包含的指定用 ...
  • Java為我們提供了許多啟動線程和管理線程的方法。在本文中,我們將介紹一些在Java中進行併發編程的選項。我們將介紹結構化併發的概念,然後討論Java 21中一組預覽類——它使將任務拆分為子任務、收集結果並對其進行操作變得非常容易,而且不會不小心留下任何掛起的任務。 1 基礎方法 通過Lambda表 ...
  • 1 問題復現 (1)登錄DVMA後,設置DVWA Security為Low。 (2)進入File Inclusion,訪問dvwa/vulnerabilities/fi目錄下的的test.txt文件(自己創建的測試文件)。 (3)報錯ERROR: File not found! 找不到文件。 2 抓 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...