คู่มือสไตล์โค้ด

รูปแบบโค้ด HIDL มีลักษณะคล้ายกับโค้ด C++ ในเฟรมเวิร์ก Android โดยมีการเยื้อง 4 ช่องและชื่อไฟล์แบบตัวพิมพ์เล็กและใหญ่ การประกาศแพ็กเกจ การนำเข้า และสตริงเอกสารจะคล้ายกับใน Java โดยมีการแก้ไขเล็กน้อย

ตัวอย่างต่อไปนี้สำหรับ IFoo.hal และ types.hal แสดงให้เห็นสไตล์โค้ด HIDL และให้ลิงก์ด่วนไปยังรายละเอียดเกี่ยวกับแต่ละสไตล์ ( IFooClientCallback.hal , IBar.hal และ IBaz.hal ถูกละเว้น)

hardware/interfaces/foo/1.0/IFoo.hal
/*
 * (License Notice)
 */

package android.hardware.foo@1.0;

import android.hardware.bar@1.0::IBar;

import IBaz;
import IFooClientCallback;

/**
 * IFoo is an interface that…
 */
interface IFoo {

    /**
     * This is a multiline docstring.
     *
     * @return result 0 if successful, nonzero otherwise.
     */
     foo() generates (FooStatus result);

    /**
     * Restart controller by power cycle.
     *
     * @param bar callback interface that…
     * @return result 0 if successful, nonzero otherwise.
     */
    powerCycle(IBar bar) generates (FooStatus result);

    /** Single line docstring. */
    baz();


    /**
     * The bar function.
     *
     * @param clientCallback callback after function is called
     * @param baz related baz object
     * @param data input data blob
     */
    bar(IFooClientCallback clientCallback,
        IBaz baz,
        FooData data);

};
hardware/interfaces/foo/1.0/types.hal
/*
 * (License Notice)
 */

package android.hardware.foo@1.0;

/** Replied status. */
enum Status : int32_t {
    OK,
    /* invalid arguments */
    ERR_ARG,
    /* note, no transport related errors */
    ERR_UNKNOWN = -1,
};

struct ArgData {
    int32_t[20]  someArray;
    vec<uint8_t> data;
};

แบบแผนการตั้งชื่อ

ชื่อฟังก์ชัน ชื่อตัวแปร และชื่อไฟล์ควรเป็นคำอธิบาย หลีกเลี่ยงการใช้คำย่อมากเกินไป ถือว่าคำย่อเป็นเหมือนคำ (เช่น ใช้ INfc แทน INFC )

โครงสร้างไดเรกทอรีและการตั้งชื่อไฟล์

โครงสร้างไดเร็กทอรีควรปรากฏดังนี้:

  • ROOT-DIRECTORY
    • MODULE
      • SUBMODULE (เป็นทางเลือก อาจมีมากกว่าหนึ่งระดับ)
        • VERSION
          • Android.mk
          • I INTERFACE_1 .hal
          • I INTERFACE_2 .hal
          • I INTERFACE_N .hal
          • types.hal (ไม่จำเป็น)

ที่ไหน:

  • ROOT-DIRECTORY คือ:
    • hardware/interfaces สำหรับแพ็คเกจ HIDL หลัก
    • vendor/ VENDOR /interfaces สำหรับแพ็คเกจของผู้จำหน่าย โดยที่ VENDOR อ้างถึงผู้จำหน่าย SoC หรือ OEM/ODM
  • MODULE ควรเป็นคำตัวพิมพ์เล็กหนึ่งคำที่อธิบายระบบย่อย (เช่น nfc ) หากต้องการมากกว่าหนึ่งคำ ให้ใช้ SUBMODULE แบบซ้อน การซ้อนสามารถมีได้มากกว่าหนึ่งระดับ
  • VERSION ควรเป็นเวอร์ชันเดียวกันทุกประการ (major.minor) ตามที่อธิบายไว้ใน Versions
  • I INTERFACE_X ควรเป็นชื่ออินเทอร์เฟซที่มี UpperCamelCase / PascalCase (เช่น INfc ) ตามที่อธิบายไว้ใน ชื่ออินเทอร์เฟซ

ตัวอย่าง:

  • hardware/interfaces
    • nfc
      • 1.0
        • Android.mk
        • INfc.hal
        • INfcClientCallback.hal
        • types.hal

หมายเหตุ: ไฟล์ทั้งหมดจะต้องมีสิทธิ์ที่ไม่สามารถปฏิบัติการได้ (ใน Git)

ชื่อแพ็คเกจ

ชื่อแพ็คเกจต้องใช้รูปแบบ ชื่อแบบเต็ม (FQN) ต่อไปนี้ (เรียกว่า PACKAGE-NAME ):

PACKAGE.MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION

ที่ไหน:

  • PACKAGE คือแพ็คเกจที่แมปกับ ROOT-DIRECTORY โดยเฉพาะอย่างยิ่ง PACKAGE คือ:
    • android.hardware สำหรับแพ็คเกจ HIDL หลัก (การแมปกับ hardware/interfaces )
    • vendor. VENDOR .hardware สำหรับแพ็คเกจของผู้จำหน่าย โดยที่ VENDOR อ้างถึงผู้จำหน่าย SoC หรือ OEM/ODM (การแมปกับ vendor/ VENDOR /interfaces )
  • MODULE [. SUBMODULE [. SUBMODULE […]]]@ VERSION เป็นชื่อโฟลเดอร์เดียวกันทุกประการในโครงสร้างที่อธิบายไว้ใน โครงสร้างไดเรกทอรี
  • ชื่อแพ็คเกจควรเป็นตัวพิมพ์เล็ก หากมีความยาวมากกว่าหนึ่งคำ คำนั้นควรใช้เป็นโมดูลย่อยหรือเขียนเป็น snake_case
  • ไม่อนุญาตให้มีช่องว่าง

FQN ใช้ในการประกาศแพ็คเกจเสมอ

รุ่นต่างๆ

เวอร์ชันควรมีรูปแบบดังต่อไปนี้:

MAJOR.MINOR

ทั้งเวอร์ชัน MAJOR และ MINOR ควรเป็นจำนวนเต็มตัวเดียว HIDL ใช้กฎ การกำหนดเวอร์ชันเชิงความหมาย

นำเข้า

การนำเข้ามีรูปแบบใดรูปแบบหนึ่งจากสามรูปแบบต่อไปนี้:

  • การนำเข้าทั้งแพ็คเกจ: import PACKAGE-NAME ;
  • การนำเข้าบางส่วน: import PACKAGE-NAME :: UDT ; (หรือหากประเภทที่นำเข้าอยู่ในแพ็คเกจเดียวกัน import UDT ;
  • การนำเข้าเฉพาะประเภท: import PACKAGE-NAME ::types;

PACKAGE-NAME เป็นไปตามรูปแบบใน ชื่อแพ็คเกจ types.hal ของแพ็คเกจปัจจุบัน (ถ้ามี) จะถูกนำเข้าโดยอัตโนมัติ (อย่านำเข้าอย่างชัดเจน)

ชื่อที่มีคุณสมบัติครบถ้วน (FQN)

ใช้ชื่อแบบเต็มสำหรับการนำเข้าประเภทที่ผู้ใช้กำหนดเมื่อจำเป็นเท่านั้น ละเว้น PACKAGE-NAME หากประเภทการนำเข้าอยู่ในแพ็คเกจเดียวกัน FQN ต้องไม่มีการเว้นวรรค ตัวอย่างของชื่อที่มีคุณสมบัติครบถ้วน:

android.hardware.nfc@1.0::INfcClientCallback

ในไฟล์อื่นภายใต้ android.hardware.nfc@1.0 ให้อ้างถึงอินเทอร์เฟซด้านบนเป็น INfcClientCallback มิฉะนั้น ให้ใช้เฉพาะชื่อที่มีคุณสมบัติครบถ้วนเท่านั้น

การจัดกลุ่มและการสั่งนำเข้า

ใช้บรรทัดว่างหลังการประกาศบรรจุภัณฑ์ (ก่อนการนำเข้า) การนำเข้าแต่ละครั้งควรใช้บรรทัดเดียวและไม่ควรเยื้อง การนำเข้าแบบกลุ่มตามลำดับต่อไปนี้:

  1. แพ็คเกจ android.hardware อื่นๆ (ใช้ชื่อที่มีคุณสมบัติครบถ้วน)
  2. vendor. VENDOR แพ็คเกจ vendor. VENDOR (ใช้ชื่อที่มีคุณสมบัติครบถ้วน)
    • ผู้ขายแต่ละรายควรเป็นกลุ่ม
    • สั่งซื้อผู้ขายตามลำดับตัวอักษร
  3. นำเข้าจากอินเทอร์เฟซอื่นในแพ็คเกจเดียวกัน (ใช้ชื่อธรรมดา)

ใช้บรรทัดว่างระหว่างกลุ่ม ภายในแต่ละกลุ่ม ให้เรียงลำดับการนำเข้าตามตัวอักษร ตัวอย่าง:

import android.hardware.nfc@1.0::INfc;
import android.hardware.nfc@1.0::INfcClientCallback;

/* Importing the whole module. */
import vendor.barvendor.bar@3.1;

import vendor.foovendor.foo@2.2::IFooBar;
import vendor.foovendor.foo@2.2::IFooFoo;

import IBar;
import IFoo;

ชื่ออินเทอร์เฟซ

ชื่ออินเทอร์เฟซต้องขึ้นต้นด้วย I ตามด้วยชื่อ UpperCamelCase / PascalCase ต้องกำหนดอินเทอร์เฟซชื่อ IFoo ในไฟล์ IFoo.hal ไฟล์นี้สามารถมีคำจำกัดความสำหรับอินเทอร์เฟซ IFoo เท่านั้น (อินเทอร์เฟ I NAME ควรอยู่ใน I NAME .hal )

ฟังก์ชั่น

สำหรับชื่อฟังก์ชัน อาร์กิวเมนต์ และชื่อตัวแปรที่ส่งคืน ให้ใช้ lowerCamelCase ตัวอย่าง:

open(INfcClientCallback clientCallback) generates (int32_t retVal);
oneway pingAlive(IFooCallback cb);

ชื่อฟิลด์โครงสร้าง/สหภาพ

สำหรับชื่อฟิลด์ struct/union ให้ใช้ lowerCamelCase ตัวอย่าง:

struct FooReply {
    vec<uint8_t> replyData;
}

พิมพ์ชื่อ

ชื่อประเภทอ้างอิงถึงคำจำกัดความของโครงสร้าง/สหภาพ คำจำกัดความประเภทแจงนับ และ typedef s สำหรับชื่อเหล่านี้ ให้ใช้ UpperCamelCase / PascalCase ตัวอย่าง:

enum NfcStatus : int32_t {
    /*...*/
};
struct NfcData {
    /*...*/
};

ค่าแจงนับ

ค่าแจงนับควรเป็น UPPER_CASE_WITH_UNDERSCORES เมื่อส่งค่าแจงนับเป็นอาร์กิวเมนต์ของฟังก์ชันและส่งคืนค่าเป็นฟังก์ชันส่งคืน ให้ใช้ประเภทแจงนับตามจริง (ไม่ใช่ประเภทจำนวนเต็มพื้นฐาน) ตัวอย่าง:

enum NfcStatus : int32_t {
    HAL_NFC_STATUS_OK               = 0,
    HAL_NFC_STATUS_FAILED           = 1,
    HAL_NFC_STATUS_ERR_TRANSPORT    = 2,
    HAL_NFC_STATUS_ERR_CMD_TIMEOUT  = 3,
    HAL_NFC_STATUS_REFUSED          = 4
};

หมายเหตุ: ประเภทพื้นฐานของประเภท enum ได้รับการประกาศอย่างชัดเจนหลังเครื่องหมายทวิภาค เนื่องจากไม่ได้ขึ้นอยู่กับคอมไพเลอร์ การใช้ประเภท enum จริงจึงชัดเจนกว่า

สำหรับชื่อแบบเต็มสำหรับค่า enum จะใช้ โคลอน ระหว่างชื่อประเภท enum และชื่อค่า enum:

PACKAGE-NAME::UDT[.UDT[.UDT[…]]:ENUM_VALUE_NAME

ต้องไม่มีการเว้นวรรคในชื่อที่มีคุณสมบัติครบถ้วน ใช้ชื่อที่มีคุณสมบัติครบถ้วนเมื่อจำเป็นเท่านั้น และละเว้นส่วนที่ไม่จำเป็น ตัวอย่าง:

android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK

ความคิดเห็น

สำหรับความคิดเห็นบรรทัดเดียว // , /* */ และ /** */ ก็ใช้ได้

// This is a single line comment
/* This is also single line comment */
/** This is documentation comment */
  • ใช้ /* */ ในการแสดงความคิดเห็น แม้ว่า HIDL จะรองรับ // สำหรับความคิดเห็น แต่ก็ไม่สนับสนุนเนื่องจากไม่ปรากฏในเอาต์พุตที่สร้างขึ้น
  • ใช้ /** */ สำหรับเอกสารที่สร้างขึ้น สิ่งเหล่านี้สามารถใช้ได้เฉพาะกับการประกาศประเภท วิธีการ ฟิลด์ และค่าแจงนับเท่านั้น ตัวอย่าง:
    /** Replied status */
    enum TeleportStatus {
        /** Object entirely teleported. */
        OK              = 0,
        /** Methods return this if teleportation is not completed. */
        ERROR_TELEPORT  = 1,
        /**
         * Teleportation could not be completed due to an object
         * obstructing the path.
         */
        ERROR_OBJECT    = 2,
        ...
    }
    
  • เริ่มความคิดเห็นหลายบรรทัดด้วย /** ในบรรทัดแยก ใช้ * ที่จุดเริ่มต้นของแต่ละบรรทัด ปิดท้ายความคิดเห็นด้วย */ ในบรรทัดแยกกัน โดยจัดเครื่องหมายดอกจัน ตัวอย่าง:
    /**
     * My multi-line
     * comment
     */
    
  • ประกาศเกี่ยวกับลิขสิทธิ์และบันทึกการเปลี่ยนแปลงควรขึ้นบรรทัดใหม่ด้วย /* (เครื่องหมายดอกจันเดียว) ใช้ * ที่จุดเริ่มต้นของแต่ละบรรทัด และวาง */ ในบรรทัดสุดท้ายทั้งหมดด้วยตัวมันเอง (เครื่องหมายดอกจันควรจัดเรียง) ตัวอย่าง:
    /*
     * Copyright (C) 2017 The Android Open Source Project
     * ...
     */
    
    /*
     * Changelog:
     * ...
     */
    

แสดงความคิดเห็นไฟล์

เริ่มต้นแต่ละไฟล์ด้วยประกาศสิทธิ์การใช้งานที่เหมาะสม สำหรับ HAL หลัก นี่ควรเป็นใบอนุญาต AOSP Apache ใน development/docs/copyright-templates/c.txt อย่าลืมอัปเดตปีและใช้ /* */ ลักษณะความคิดเห็นหลายบรรทัดตามที่อธิบายไว้ข้างต้น

คุณสามารถเลือกเว้นบรรทัดว่างไว้หลังประกาศใบอนุญาต ตามด้วยบันทึกการเปลี่ยนแปลง/ข้อมูลเวอร์ชัน ใช้ /* */ จัดรูปแบบความคิดเห็นหลายบรรทัดตามที่อธิบายไว้ข้างต้น วางบรรทัดว่างหลังบันทึกการเปลี่ยนแปลง จากนั้นตามด้วยการประกาศแพ็คเกจ

สิ่งที่ต้องทำ

TODO ควรรวมสตริง TODO ในตัวพิมพ์ใหญ่ทั้งหมดตามด้วยเครื่องหมายทวิภาค ตัวอย่าง:

// TODO: remove this code before foo is checked in.

อนุญาตให้แสดงความคิดเห็นของ TODO ในระหว่างการพัฒนาเท่านั้น ต้องไม่มีอยู่ในอินเทอร์เฟซที่เผยแพร่

ความคิดเห็นเกี่ยวกับอินเทอร์เฟซ/ฟังก์ชัน (สตริงเอกสาร)

ใช้ /** */ สำหรับเอกสารหลายบรรทัดและบรรทัดเดียว ห้ามใช้ // สำหรับสตริงเอกสาร

เอกสารสำหรับอินเทอร์เฟซควรอธิบายกลไกทั่วไปของอินเทอร์เฟซ เหตุผลการออกแบบ วัตถุประสงค์ ฯลฯ เอกสารสำหรับฟังก์ชันควรมีความเฉพาะเจาะจงสำหรับฟังก์ชัน (เอกสารประกอบระดับแพ็กเกจอยู่ในไฟล์ README ในไดเร็กทอรีแพ็กเกจ)

/**
 * IFooController is the controller for foos.
 */
interface IFooController {
    /**
     * Opens the controller.
     *
     * @return status HAL_FOO_OK if successful.
     */
    open() generates (FooStatus status);

    /** Close the controller. */
    close();
};

คุณต้องเพิ่ม @param s และ @return s สำหรับแต่ละพารามิเตอร์/ค่าส่งคืน:

  • ต้องเพิ่ม @param สำหรับแต่ละพารามิเตอร์ ควรตามด้วยชื่อของพารามิเตอร์ ตามด้วย docstring
  • ต้องเพิ่ม @return สำหรับค่าตอบแทนแต่ละรายการ ควรตามด้วยชื่อของค่าที่ส่งคืน จากนั้นตามด้วย docstring

ตัวอย่าง:

/**
 * Explain what foo does.
 *
 * @param arg1 explain what arg1 is
 * @param arg2 explain what arg2 is
 * @return ret1 explain what ret1 is
 * @return ret2 explain what ret2 is
 */
foo(T arg1, T arg2) generates (S ret1, S ret2);

การจัดรูปแบบ

กฎการจัดรูปแบบทั่วไปได้แก่:

  • ความยาวสาย . ข้อความแต่ละบรรทัดควรมีความยาวไม่เกิน 100 คอลัมน์
  • ช่องว่าง ไม่มีช่องว่างต่อท้ายบนบรรทัด บรรทัดว่างต้องไม่มีช่องว่าง
  • ช่องว่างกับแท็บ ใช้ช่องว่างเท่านั้น
  • ขนาดเยื้อง . ใช้ช่องว่าง 4 ช่องสำหรับบล็อก และ 8 ช่องสำหรับการตัดบรรทัด
  • การค้ำยัน ยกเว้น ค่าคำอธิบายประกอบ เครื่องหมายปีกกา แบบเปิด จะอยู่ในบรรทัดเดียวกับโค้ดก่อนหน้า แต่เครื่องหมายปีกกา ปิด และเครื่องหมายอัฒภาคต่อไปนี้จะใช้ทั้งบรรทัด ตัวอย่าง:
    interface INfc {
        close();
    };
    

ประกาศแพ็คเกจ

การประกาศบรรจุภัณฑ์ควรอยู่ที่ด้านบนของไฟล์หลังจากประกาศใบอนุญาต ควรใช้ทั้งบรรทัด และไม่ควรเยื้อง แพ็คเกจถูกประกาศโดยใช้รูปแบบต่อไปนี้ (สำหรับการจัดรูปแบบชื่อ ดูที่ ชื่อแพ็คเกจ ):

package PACKAGE-NAME;

ตัวอย่าง:

package android.hardware.nfc@1.0;

การประกาศฟังก์ชั่น

ชื่อฟังก์ชัน พารามิเตอร์ generates และค่าที่ส่งคืนควรอยู่ในบรรทัดเดียวกันหากพอดี ตัวอย่าง:

interface IFoo {
    /** ... */
    easyMethod(int32_t data) generates (int32_t result);
};

หากไม่พอดีกับบรรทัดเดียวกัน ให้พยายามใส่พารามิเตอร์และส่งคืนค่าในระดับการเยื้องเดียวกัน และแยกแยะความแตกต่าง generate เพื่อช่วยให้ผู้อ่านเห็นพารามิเตอร์และส่งคืนค่าได้อย่างรวดเร็ว ตัวอย่าง:

interface IFoo {
    suchALongMethodThatCannotFitInOneLine(int32_t theFirstVeryLongParameter,
                                          int32_t anotherVeryLongParameter);
    anEvenLongerMethodThatCannotFitInOneLine(int32_t theFirstLongParameter,
                                             int32_t anotherVeryLongParameter)
                                  generates (int32_t theFirstReturnValue,
                                             int32_t anotherReturnValue);
    superSuperSuperSuperSuperSuperSuperLongMethodThatYouWillHateToType(
            int32_t theFirstVeryLongParameter, // 8 spaces
            int32_t anotherVeryLongParameter
        ) generates (
            int32_t theFirstReturnValue,
            int32_t anotherReturnValue
        );
    /* method name is even shorter than 'generates' */
    foobar(AReallyReallyLongType aReallyReallyLongParameter,
           AReallyReallyLongType anotherReallyReallyLongParameter)
        generates (ASuperLongType aSuperLongReturnValue, // 4 spaces
                   ASuperLongType anotherSuperLongReturnValue);
}

รายละเอียดเพิ่มเติม:

  • วงเล็บเปิดจะอยู่ในบรรทัดเดียวกับชื่อฟังก์ชันเสมอ
  • ไม่มีการเว้นวรรคระหว่างชื่อฟังก์ชันและวงเล็บเปิด
  • ไม่มีช่องว่างระหว่างวงเล็บและพารามิเตอร์ ยกเว้น เมื่อมีการป้อนบรรทัดระหว่างวงเล็บ
  • หาก generates อยู่ในบรรทัดเดียวกับวงเล็บปิดก่อนหน้า ให้ใช้ช่องว่างนำหน้า หาก generates อยู่ในบรรทัดเดียวกับวงเล็บเปิดถัดไป ให้ตามด้วยช่องว่าง
  • จัดตำแหน่งพารามิเตอร์ทั้งหมดและค่าที่ส่งคืน (ถ้าเป็นไปได้)
  • การเยื้องเริ่มต้นคือ 4 ช่องว่าง
  • พารามิเตอร์ที่รวมไว้จะจัดชิดกับพารามิเตอร์แรกในบรรทัดก่อนหน้า มิฉะนั้นจะมีการเยื้อง 8 ช่องว่าง

คำอธิบายประกอบ

ใช้รูปแบบต่อไปนี้สำหรับคำอธิบายประกอบ:

@annotate(keyword = value, keyword = {value, value, value})

จัดเรียงคำอธิบายประกอบตามลำดับตัวอักษร และใช้ช่องว่างรอบเครื่องหมายเท่ากับ ตัวอย่าง:

@callflow(key = value)
@entry
@exit

ตรวจสอบให้แน่ใจว่าคำอธิบายประกอบครอบคลุมทั้งบรรทัด ตัวอย่าง:

/* Good */
@entry
@exit

/* Bad */
@entry @exit

หากคำอธิบายประกอบไม่สามารถอยู่ในบรรทัดเดียวกันได้ ให้เว้นวรรค 8 ช่อง ตัวอย่าง:

@annotate(
        keyword = value,
        keyword = {
                value,
                value
        },
        keyword = value)

หากอาร์เรย์ของค่าทั้งหมดไม่สามารถอยู่ในบรรทัดเดียวกันได้ ให้ใส่ตัวแบ่งบรรทัดหลังเครื่องหมายปีกกาเปิด { และหลังเครื่องหมายจุลภาคแต่ละตัวภายในอาร์เรย์ ใส่วงเล็บปิดไว้หลังค่าสุดท้าย อย่าใส่เครื่องหมายปีกกาหากมีเพียงค่าเดียว

หากอาร์เรย์ค่าทั้งหมดสามารถอยู่ในบรรทัดเดียวกันได้ อย่าใช้ช่องว่างหลังเครื่องหมายปีกกาแบบเปิดและก่อนเครื่องหมายปีกกาปิด และใช้ช่องว่างหนึ่งช่องหลังเครื่องหมายจุลภาคแต่ละตัว ตัวอย่าง:

/* Good */
@callflow(key = {"val", "val"})

/* Bad */
@callflow(key = { "val","val" })

จะต้องไม่มีบรรทัดว่างระหว่างคำอธิบายประกอบและการประกาศฟังก์ชัน ตัวอย่าง:

/* Good */
@entry
foo();

/* Bad */
@entry

foo();

ประกาศแจงนับ

ใช้กฎต่อไปนี้สำหรับการประกาศแจงนับ:

  • หากการประกาศ enum แชร์กับแพ็คเกจอื่น ให้ใส่การประกาศใน types.hal แทนที่จะฝังไว้ภายในอินเทอร์เฟซ
  • ใช้ช่องว่างก่อนและหลังเครื่องหมายทวิภาค และช่องว่างหลังประเภทที่อยู่ข้างหน้าเครื่องหมายปีกกาแบบเปิด
  • ค่าแจงนับสุดท้ายอาจมีหรือไม่มีเครื่องหมายจุลภาคเพิ่มเติมก็ได้

ประกาศโครงสร้าง

ใช้กฎต่อไปนี้สำหรับการประกาศโครงสร้าง:

  • หากการประกาศโครงสร้างถูกแชร์กับแพ็คเกจอื่น ให้ใส่การประกาศใน types.hal แทนที่จะฝังไว้ภายในอินเทอร์เฟซ
  • ใช้ช่องว่างหลังชื่อประเภทโครงสร้างก่อนเครื่องหมายปีกกาแบบเปิด
  • จัดแนวชื่อฟิลด์ (ไม่บังคับ) ตัวอย่าง:
    struct MyStruct {
        vec<uint8_t>   data;
        int32_t        someInt;
    }
    

การประกาศอาร์เรย์

อย่าเว้นวรรคระหว่างสิ่งต่อไปนี้:

  • ประเภทองค์ประกอบและวงเล็บเหลี่ยมเปิด
  • เปิดวงเล็บเหลี่ยมและขนาดอาร์เรย์
  • ขนาดอาร์เรย์และวงเล็บเหลี่ยมปิด
  • ปิดวงเล็บเหลี่ยมและวงเล็บเหลี่ยมเปิดถัดไป หากมีมากกว่าหนึ่งมิติ

ตัวอย่าง:

/* Good */
int32_t[5] array;

/* Good */
int32_t[5][6] multiDimArray;

/* Bad */
int32_t [ 5 ] [ 6 ] array;

เวกเตอร์

อย่าเว้นวรรคระหว่างสิ่งต่อไปนี้:

  • vec และวงเล็บมุมเปิด
  • วงเล็บมุมเปิดและประเภทองค์ประกอบ ( ข้อยกเว้น: ประเภทองค์ประกอบก็เป็น vec เช่นกัน )
  • ประเภทองค์ประกอบและวงเล็บมุมปิด ( ข้อยกเว้น: ประเภทองค์ประกอบก็เป็น vec เช่นกัน)

ตัวอย่าง:

/* Good */
vec<int32_t> array;

/* Good */
vec<vec<int32_t>> array;

/* Good */
vec< vec<int32_t> > array;

/* Bad */
vec < int32_t > array;

/* Bad */
vec < vec < int32_t > > array;