共用方式為


如何建立和管理 Q# 專案和自定義連結庫

在本文中,您將瞭解如何建立、管理和共用 Q# 專案。 專案是一種 Q# 資料夾結構,其中包含多個 Q# 文件,可以存取彼此的操作和功能。 專案可協助您以邏輯方式組織原始程式碼。 您也可以使用專案作為可從外部來源存取的自訂連結庫。

必要條件

要運行 Python 程序,您還需要:

  • 具備安裝了Python 的Python環境。

  • qdk Python庫,帶有可選的azure擴展。

    python -m pip install --upgrade "qdk[azure]"
    

項目的運作方式Q#

專案包含 Q# 名為 Q#qsharp.json的資訊清單檔案,以及指定資料夾結構中的一或多個 .qs 檔案。 您可以手動建立Q#專案,或直接在VS Code中建立。

當您在VS Code中開啟.qs檔案時,編譯器會在周圍的資料夾階層中搜尋資訊清單檔案,並決定專案的範圍。 如果找不到資訊清單檔案,則編譯器會以單一檔案模式運作。

當您在Jupyter Notebook檔案或Python檔案中設定project_root時,編譯器會在project_root資料夾中尋找資訊清單檔案。

外部 Q# 專案是位於另一個目錄或公用 GitHub 存放庫中的標準 Q# 專案,並充當自訂程式庫。 外部專案使用陳述式來 export 定義外部程式可存取的函數和作業。 程式會將外部專案定義為其資訊清單檔案中的相依性,並使用 import 陳述式來存取外部專案中的項目,例如作業、函數、結構和命名空間。 如需詳細資訊,請參閱 使用專案作為外部相依性

Q#定義專案

專案是由 Q# 名為 qsharp.json的資訊清單檔案 ( src 和資料夾) 的存在所定義,這兩個檔案都必須位於專案的根資料夾中。 資料夾包含srcQ#來源檔案。 針對 Q# 程式和外部項目,編譯程式 Q# 會自動偵測項目資料夾。 對於程式和檔案,您必須透過呼叫來指定專案資料夾。 不過,專案的 Q# 資料夾結構對於所有類型的程式都相同。

項目的資料夾結構和階層 Q# 。

定義專案資料夾(Q# 程式)

當您在.qs中開啟VS Code檔案時,Q#編譯器會向上搜尋資料夾結構中的資訊清單檔案。 如果編譯器找到資訊清單檔案,則編譯器會包含 Q# 目錄中的所有 /src 檔案及其所有子目錄。 每個檔案中定義的項目將可供專案內的所有其他檔案使用。

例如,請考慮下列資料夾結構:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

當您開啟檔案 /src/TeleportOperation/PrepareState/PrepareStateLib.qs時,編譯器會 Q# 執行下列動作:

  1. 檢查 /src/TeleportOperation/PrepareState/以尋找qsharp.json
  2. 檢查 /src/TeleportOperation以尋找qsharp.json
  3. 檢查 /src以尋找qsharp.json
  4. 檢查 /*以尋找qsharp.json
  5. /建立為專案的根目錄,並根據資訊清單檔案的設定,包含專案中根目錄下的所有.qs檔案。

建立資訊清單檔

資訊清單檔案是名為的 qsharp.json JSON 檔案,可以選擇性地包含 作者授權lints 欄位。 最小可行的指令清單檔是字串 {}。 當您在VS Code中建立Q#專案時,會為您建立一個最小化的 manifest 檔案。

{}

指令清單檔案範例

下列範例顯示資訊清單檔案如何定義專案的 Q# 範圍。

  • 在此範例中, 作者 是唯一指定的欄位,因此 .qs 此目錄及其子目錄中的所有檔案都包含在專案中 Q# 。

    {
        "author":"Microsoft",
        "license": "MIT"
    }
    
  • 在 Q# 專案中,您也可以使用資訊清單檔案來微調 VS CodeQ# Linter 設定。 根據預設,三個 Linter 規則為:

    • needlessParens:default = allow

    • divisionByZero:default = warn

    • redundantSemicolons:default = warn

      您可以將資訊清單檔案中的每個規則設定為 allow、 或 warnerror。 例如:

      {
          "author":"Microsoft",
          "lints": [
              {
                "lint": "needlessParens",
                "level": "allow"
              },
              {
                "lint": "redundantSemicolons",
                "level": "warn"
              },
              {
                "lint": "divisionByZero",
                "level": "error"
              }
            ]
      }
      
  • 您也可以使用指令清單檔,將外部 Q# 專案定義為相依性,並遠端訪問該外部專案中的作業和函式。 如需詳細資訊,請參閱 使用專案作為外部相依性

Q# 專案需求和屬性

下列需求和組態適用於所有 Q# 專案。

  • .qs您要包含在專案中的所有檔案都必須位於名為 src的資料夾下,該資料夾必須位於專案的Q#根資料夾下。 當您在VS Code中建立Q#專案時,會自動建立/src資料夾。

  • 資訊清單檔案應與資料夾位於 src 同一層級。 當您在 中Q#建立VS Code專案時,會自動建立最小檔案。

  • 使用 import 語句從專案中的其他檔案參考作業和函式。

    import MyMathLib.*;  //imports all the callables in the MyMathLib namespace
    
    ...
    
    Multiply(x,y);
    

    或者,使用命名空間個別參考它們。

    MyMathLib.Multiply(x,y); 
    

僅適用於 Q# 專案

  • 您只能在專案中的一個.qs檔案中定義入口操作,該Q#操作是默認的作業。
  • 您必須將 .qs 具有進入點定義的檔案放在資訊清單檔案下方的專案目錄層級。
  • 專案中所有從.qs快取的作業和函數將在VS Code的預測文本顯示中表現出來。
  • 如果尚未匯入所選作業或函式的命名空間,則 VS Code 會自動新增必要的 import 陳述式。

如何建立 Q# 專案

若要建立 Q# 專案,請遵循下列步驟:

  1. 在VS Code檔案總管中,前往您要用作Q#專案根資料夾的資料夾。

  2. 開啟 [檢視] 功能表,然後選擇 [命令面板]。

  3. Enter QDK:建立 Q# 專案 並按 Enter 鍵。 VS Code 在資料夾中建立最小資訊清單檔案,並新增具有 /src 範本檔案的 Main.qs 資料夾。

  4. 編輯專案的資訊清單檔案。 請參閱 指令清單檔案範例

  5. 在資料夾下Q#新增並組織您的/src原始程序檔。

  6. 如果您要從 Python 程式或 Jupyter Notebook 存取 Q# 專案,請使用 qsharp.init 設定根資料夾路徑。 此範例假設您的程式位於專案的/src資料夾中Q#:

    qsharp.init(project_root = '../Teleportation_project')
    
  7. 如果您只使用 Q# 檔案在 VS Code,則當您開啟 Q# 檔案時,編譯器會搜尋清單檔,判斷專案的根資料夾,然後掃描子資料夾中的 .qs 檔案。

注意

您也可以手動建立資訊清單檔案和 /src 資料夾。

範例專案

這個量子傳輸程式是運行於Q#本地模擬器中的專案範例VS Code。 若要在Azure Quantum硬體或協力廠商模擬器上執行程式,請參閱開始使用Q#程式及VS Code,以取得編譯程式及連線至Azure Quantum工作區的步驟。

此範例具有下列目錄結構:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

指令清單檔案包含 作者授權 欄位:

{
    "author":"Microsoft",
    "license":"MIT"
}

Q# 來源檔案

主檔案 Main.qs 包含進入點,並且從 TeleportOperations.TeleportLib 引用 TeleportLib.qs 命名空間。

    import TeleportOperations.TeleportLib.Teleport; // references the Teleport operation from TeleportLib.qs

    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();

        H(msg);
        Teleport(msg, target); // calls the Teleport() operation from TeleportLib.qs
        H(target);

        if M(target) == Zero {
            Message("Teleported successfully!");
        
        Reset(msg);
        Reset(target);
        }
    }

檔案 TeleportLib.qs 定義 Teleport 作業,並從檔案 PrepareBellPair 呼叫 PrepareStateLib.qs 作業。

    import TeleportOperations.PrepareState.PrepareStateLib.*; // references the namespace in PrepareStateLib.qs
 
    operation Teleport(msg : Qubit, target : Qubit) : Unit {
        use here = Qubit();

        PrepareBellPair(here, target); // calls the PrepareBellPair() operation from PrepareStateLib.qs
        Adjoint PrepareBellPair(msg, here);

        if M(msg) == One { Z(target); }
        if M(here) == One { X(target); }

        Reset(here);
    }

PrepareStateLib.qs 檔案包含建立貝爾配對的標準可重複使用操作。

    operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
        H(left);
        CNOT(left, right);
    }

執行程式

選擇您執行程序之環境的標籤。

若要執行此程式,請開啟檔案Main.qsVS Code,然後選擇 [執行]。

將 Q# 專案配置為外部相依專案

您可以將專案設定 Q# 為其他專案的外部相依性,類似於程式庫。 外部 Q# 專案中的功能和作業可供多個 Q# 專案使用。 外部相依性可以位於雲端硬碟共用上,也可以發佈至公用 GitHub 存放庫。

若要將 Q# 專案作為外部相依性使用,您必須:

  • 將外部專案新增為呼叫專案的指令清單檔中的相依性。
  • 如果外部專案已發佈至 GitHub,請將 files 屬性新增至外部專案的資訊清單檔案。
  • 將語句新增 export 至外部專案。
  • 將語句新增 import 至呼叫的專案。

設定資訊清單檔案

外部 Q# 專案可以位於本機或網路磁碟機共用上,或發佈至公用 GitHub 存放庫。

呼叫的專案指令清單檔

若要將相依性新增至磁碟驅動器共用上的外部專案,請在呼叫專案的指令清單檔中定義相依性。

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyDependency": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

在上述資訊清單檔案中, MyDependency 是使用者定義的字串,可在您呼叫作業時識別命名空間。 例如,如果您建立名為 MyMathFunctions 的相依關係,則可以使用 MyMathFunctions.MyFunction() 呼叫該相依關係中的函數。

若要將相依性新增至發佈至公用 GitHub 存放庫的專案,請使用下列範例資訊清單檔案:

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
    }
}

注意

對於 GitHub 相依性, ref 會參考 GitHub refspec。 Microsoft 建議您一律使用 commit hash,以便可以依賴特定版本的依賴項。

外部專案指令清單檔

如果您的外部 Q# 專案已發佈至公用 GitHub 儲存庫,則必須將 files 屬性新增至外部專案的資訊清單檔案,包括專案中使用的所有檔案。

{
    "author": "Microsoft",
    "license": "MIT",
    "files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}

files 屬性是選擇性的,適用於匯入的"path"外部專案 (也就是本機檔案路徑型匯入)。 只有發佈至 GitHub 的專案才需要 files 屬性。

使用 export 陳述式

若要讓呼叫專案可存取外部專案中的函數和作業,請使用 陳述 export 式。 您可以匯出檔案中的任何或所有可呼叫者。 不支援通配符語法,因此您必須指定要匯出的每個可呼叫項目。

operation Operation_A() : Unit {
...
}
operation Operation_B() : Unit  {
...
}

// makes just Operation_A available to calling programs
export Operation_A;

// makes Operation_A and Operation_B available to calling programs 
export Operation_A, Operation_B, etc.; 

// makes Operation_A available as 'OpA'
export Operation_A as OpA;

使用 import 陳述式

若要讓外部相依關係中的項目可供使用,請使用 import 呼叫程式中的陳述式。 import 陳述式使用資訊清單檔案内為相依性所定義的命名空間。

例如,請考慮下列資訊清單檔案中的相依性:

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyMathFunctions": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

使用下列程式碼匯入可呼叫項目:

import MyMathFunctions.MyFunction;  // imports "MyFunction()" from the namespace

...

import 陳述式也支援萬用字元語法和別名。

// imports all items from the "MyMathFunctions" namespace
import MyMathFunctions.*; 

// imports the namespace as "Math", all items are accessible via "Math.<callable>"
import MyMathFunctions as Math;

// imports a single item, available in the local scope as "Add"
import MyMathFunctions.MyFunction as Add;

// imports can be combined on one line
import MyMathFunctions.MyFunction, MyMathFunctions.AnotherFunction as Multiply; 

注意

中目前使用的 open 語句 Q#,用於參考連結庫和命名空間,仍受支援,但最終將會被取代。 同時,您可以選擇性地更新目前的檔案以使用 import 語句。 例如, open Std.Diagnostics; 可以取代為 import Std.Diagnostics.*;

范例外部專案

在此範例中,您使用與先前範例相同的傳送程式,但將呼叫程式及可呼叫項目分隔成不同的專案。

  1. 在本機磁碟機上建立兩個資料夾,例如 Project_AProject_B

  2. 在每個資料夾中建立專案 Q# 。 如需詳細資訊,請參閱 如何建立 Q# 專案中的步驟。

  3. Project_A 中的呼叫程式中,將以下程式碼複製到資訊清單檔案中,但根據需要編輯 Project_B 的路徑:

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. Project_A中,將以下程式碼複製到 Main.qs

    import MyTeleportLib.Teleport; // imports the Teleport operation from the MyTeleportLib namespace defined in the manifest file
    
    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();
    
        H(msg);
        Teleport(msg, target); // calls the Teleport() operation from the MyTeleportLib namespace
        H(target);
    
        if M(target) == Zero {
            Message("Teleported successfully!");
    
        Reset(msg);
        Reset(target);
        }
    }   
    
  5. Project_B中,將以下程式碼複製到 Main.qs

        operation Teleport(msg : Qubit, target : Qubit) : Unit {
            use here = Qubit();
    
            PrepareBellPair(here, target); 
            Adjoint PrepareBellPair(msg, here);
    
            if M(msg) == One { Z(target); }
            if M(here) == One { X(target); }
    
            Reset(here);
        }
    
        operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
            H(left);
            CNOT(left, right);
        }
    
        export Teleport;       //  makes the Teleport operation available to external programs
    

    注意

    請注意,不需要匯出該 PrepareBellPair 操作,因為它不是直接從 中的程式 Project_A呼叫的。 因為PrepareBellPair位於Project_B的本機範圍內,Teleport操作已經可以存取它。

  6. 若要執行程式,請開啟 /Project_A/Main.qs 並 VS Code 選擇 [執行]。

專案和隱含命名空間

在專案中 Q# ,如果程式中 .qs 未指定命名空間,則編譯器會使用檔案名稱作為命名空間。 然後,當您從外部依賴參照可呼叫項目時,請使用語法 <dependencyName>.<namespace>.<callable>。 不過,如果檔案命名Main.qs為 ,則編譯器會假設命名空間及呼叫語法為 <dependencyName>.<callable>,如上一個範例所示。 import MyTeleportLib.Teleport

因為您可能有多個專案文件,所以在參照可呼叫物件時,需要考慮正確的語法。 例如,假設專案具有下列檔案結構:

  • /src
    • Main.qs
    • 數學函數.qs

下列程式碼會呼叫外部相依性:

import MyTeleportLib.MyFunction;        // "Main" namespace is implied

import MyTeleportLib.MathFunctions.MyFunction;   // "Math" namespace must be explicit 

如需命名空間行為的詳細資訊,請參閱 使用者命名空間