कोड स्टाइल गाइड

HIDL कोड शैली 4-स्पेस इंडेंट और मिश्रित-केस फ़ाइल नाम के साथ एंड्रॉइड फ्रेमवर्क में C ++ कोड जैसा दिखता है। पैकेज घोषणाएं, आयात और डॉकस्ट्रिंग जावा के समान हैं, जिनमें मामूली संशोधन हैं।

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 के बजाय 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
    • vendor/ VENDOR /interfaces , जहां VENDOR एक एसओसी विक्रेता या एक ओईएम/ओडीएम को संदर्भित करता है।
  • MODULE एक लोअरकेस शब्द होना चाहिए जो सबसिस्टम (जैसे nfc ) का वर्णन करता हो। यदि एक से अधिक शब्दों की आवश्यकता है, तो नेस्टेड SUBMODULE का उपयोग करें। नेस्टिंग के एक से अधिक स्तर हो सकते हैं।
  • VERSION ठीक वैसा ही संस्करण (major.minor) होना चाहिए जैसा कि संस्करण में वर्णित है।
  • I INTERFACE_X को UpperCamelCase / PascalCase (जैसे INfc ) के साथ इंटरफ़ेस नाम होना चाहिए जैसा कि इंटरफ़ेस नामों में वर्णित है।

उदाहरण:

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

नोट: सभी फाइलों में गैर-निष्पादन योग्य अनुमतियां होनी चाहिए (गिट में)।

पैकेज के नाम

पैकेज नामों में निम्नलिखित पूर्ण-योग्य नाम (FQN) प्रारूप (जिसे PACKAGE-NAME कहा जाता है) का उपयोग करना चाहिए:

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

कहाँ पे:

  • PACKAGE वह पैकेज है जो ROOT-DIRECTORY को मैप करता है। विशेष रूप से, PACKAGE है:
    • कोर android.hardware पैकेज के लिए android.हार्डवेयर ( hardware/interfaces पर मैपिंग)।
    • vendor. VENDOR .hardware विक्रेता पैकेज के लिए विक्रेता vendor. VENDOR .hardware , जहां विक्रेता एक VENDOR विक्रेता या एक 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 (यदि यह मौजूद है) स्वचालित रूप से आयात किया जाता है (इसे स्पष्ट रूप से आयात न करें)।

पूरी तरह से योग्य नाम (एफक्यूएन)

उपयोगकर्ता-परिभाषित प्रकार के आयात के लिए पूरी तरह से योग्य नामों का उपयोग केवल आवश्यक होने पर ही करें। यदि आयात प्रकार एक ही पैकेज में है तो PACKAGE-NAME को छोड़ दें। एक FQN में रिक्तियाँ नहीं होनी चाहिए। पूरी तरह से योग्य नाम का उदाहरण:

android.hardware.nfc@1.0::INfcClientCallback

android.hardware.nfc@1.0 के अंतर्गत एक अन्य फ़ाइल में, उपरोक्त इंटरफ़ेस को INfcClientCallback के रूप में देखें। अन्यथा, केवल पूर्णतः योग्य नाम का ही उपयोग करें।

आयात का समूह बनाना और आदेश देना

पैकेज घोषणा (आयात से पहले) के बाद एक खाली लाइन का प्रयोग करें। प्रत्येक आयात को एक ही लाइन पर कब्जा करना चाहिए और इंडेंट नहीं होना चाहिए। निम्नलिखित क्रम में समूह आयात करें:

  1. अन्य android.hardware .हार्डवेयर पैकेज (पूरी तरह से योग्य नामों का उपयोग करें)।
  2. अन्य 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);

संरचना/संघ क्षेत्र के नाम

संरचना/संघ फ़ील्ड नामों के लिए, lowerCamelCase का उपयोग करें। उदाहरण:

struct FooReply {
    vec<uint8_t> replyData;
}

नाम टाइप करें

प्रकार के नाम संरचना/संघ परिभाषाओं, एनम प्रकार की परिभाषाओं और typedef एस को संदर्भित करते हैं। इन नामों के लिए, UpperCamelCase / PascalCase का उपयोग करें। उदाहरण:

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

एनम मान

Enum मान 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
};

नोट: एक एनम प्रकार का अंतर्निहित प्रकार स्पष्ट रूप से कोलन के बाद घोषित किया गया है। चूंकि यह कंपाइलर निर्भर नहीं है, वास्तविक एनम प्रकार का उपयोग करना स्पष्ट है।

एनम मानों के लिए पूरी तरह से योग्य नामों के लिए, एनम प्रकार के नाम और एनम मान नाम के बीच एक कोलन का उपयोग किया जाता है:

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:
     * ...
     */
    

फ़ाइल टिप्पणियाँ

प्रत्येक फ़ाइल को उपयुक्त लाइसेंसिंग नोटिस के साथ प्रारंभ करें। कोर HALs के लिए, यह development/docs/copyright-templates/c.txt में AOSP Apache लाइसेंस होना चाहिए। जैसा कि ऊपर बताया गया है, वर्ष को अपडेट करना और /* */ शैली बहु-पंक्ति टिप्पणियों का उपयोग करना याद रखें।

आप वैकल्पिक रूप से लाइसेंस नोटिस के बाद एक खाली लाइन रख सकते हैं, उसके बाद चेंजलॉग/संस्करण जानकारी। ऊपर बताए अनुसार /* */ शैली बहु-पंक्ति टिप्पणियों का उपयोग करें, चैंज के बाद खाली लाइन रखें, फिर पैकेज घोषणा के साथ पालन करें।

TODO टिप्पणियाँ

TODO में स्ट्रिंग TODO को सभी कैप्स में और उसके बाद कोलन में शामिल करना चाहिए। उदाहरण:

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

TODO टिप्पणियों की अनुमति केवल विकास के दौरान ही दी जाती है; वे प्रकाशित इंटरफेस में मौजूद नहीं होना चाहिए।

इंटरफ़ेस/फ़ंक्शन टिप्पणियां (डॉकस्ट्रिंग्स)

मल्टी-लाइन और सिंगल लाइन डॉकस्ट्रिंग के लिए /** */ का उपयोग करें। डॉकस्ट्रिंग के लिए // का उपयोग न करें।

इंटरफेस के लिए डॉकस्ट्रिंग्स को इंटरफेस के सामान्य तंत्र, डिजाइन तर्क, उद्देश्य, आदि का वर्णन करना चाहिए। कार्यों के लिए डॉकस्ट्रिंग्स फ़ंक्शन के लिए विशिष्ट होना चाहिए (पैकेज-स्तरीय दस्तावेज पैकेज निर्देशिका में रीडमे फ़ाइल में जाता है)।

/**
 * 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 प्रत्येक पैरामीटर के लिए जोड़ा जाना चाहिए। इसके बाद पैरामीटर के नाम के बाद डॉकस्ट्रिंग होना चाहिए।
  • प्रत्येक वापसी मूल्य के लिए @return जोड़ा जाना चाहिए। इसके बाद वापसी मूल्य के नाम के बाद डॉकस्ट्रिंग होना चाहिए।

उदाहरण:

/**
 * 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;