0% found this document useful (0 votes)
22 views276 pages

中文版

Uploaded by

qq992825746
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views276 pages

中文版

Uploaded by

qq992825746
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 276

Google

May 29, 2022


Contents

1 Google 1

2 C++ - 3
2.1 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6 5. Google . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.7 6. C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.8 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.9 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
2.10 9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.11 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
2.12 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

3 Objective-C - 83
3.1 Google Objective-C Style Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.5 Cocoa Objective-C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
3.6 Cocoa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

4 Python - 111
4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.3 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
4.4 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

i
5 Shell - 153
5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
5.3 Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
5.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
5.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
5.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
5.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
5.10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

6 Javascript - 173
6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
6.2 Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
6.3 Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

7 TypeScript 227
7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
7.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
7.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
7.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
7.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
7.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

ii
CHAPTER 1

Google

• ReadTheDocs

• GitHub zh-google-styleguide

• release

Note:

Google

Google Google Style Guide

camelCase

Google Google

1. Google C++

2. Google Objective-C

3. Google Python

4. Google JavaScript

5. Google Shell

1
Google

6. Google JSON

7. Google TypeScript

reStructuredText Sphinx HTML / CHM / PDF

• cpplint google-c-style.el Google


Emacs

• JavaScript Style Guide XML Document Format Style Guide


Yang.Y

2 Chapter 1. Google
CHAPTER 2

C++ -

Contents

• C++ -

2.1 0.

4.45

Benjy Weinberger
Craig Silverstein
Gregory Eitzmann
Mark Mentovai
Tashana Landray

YuleFox
Yang.Y
acgtyrant
lilinsanity

• Google Style Guide

3
Google

• Google -

2.1.1 0.1

Google , .
Google , . Google
, Google .

. , , .
, , , .

Google ,5 , .
. ,
.

, , ,
. , , Google
, . , ,
.

, . .

, , bug . , .

, Artistic License/GPL .

• 2015-08 : @lilinsanity Google


CPP Style Guide 4.45

• 2015-07 4.45 : acgtyrant C++ C++ C++11


Google C++
innocentim,
farseerfc Arch Linux C++ Primer

• 2009-06 3.133 : YuleFox 1.0 , ,


.

Yang.Y YuleFox , : Google -


.

3.133 , ,
. Yang.Y , YuleFox .

• 2008-07 1.0 : YuleFox Blog, .

4 Chapter 2. C++ -
Google

2.1.2 0.2

C++ Google . C++ , C++


, bug, .

C++ . ,
C++ .

, , C++ . ,
.

. .
.
, . ,
.

C++ . C++ . ,
. , .
, .

Google .

: C++ , C++ .

2.2 1.

.cc .h . , main()
.cc .

2.2.1 1.1. Self-contained

Tip: self-contained, .h
.inc -inl.h
.

1.2. #define symbols.

self-contained
platform-specific .inc

.h .cc
-inl.h
-inl.h

2.2. 1. 5
Google

.cc

2.2.2 1.2. #define

Tip: #define , :
<PROJECT>_<PATH>_<FILE>_H_ .

, . , foo foo/
src/bar/baz.h :

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

2.2.3 1.3.

Tip: #include

forward declaration .

• #include

• #include


API.

• std:: symbol

• #include
#include

// b.h:
struct B {};
struct D : B {};
(continues on next page)

6 Chapter 2. C++ -
Google

(continued from previous page)

// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)

#include B D test() f(void*) .

• symbol include


.

• .

• #include.

• #include.

1.5. #include

2.2.4 1.4.

Tip: 10 .

, ,
.

, .
, , .

. , .
,
. ,

, 10 . ,
, !

: switch (
, switch ).

2.2. 1. 7
Google

, ;
. , . YuleFox :
, ,
). , ,
, .

2.2.5 1.5. #include

Tip: , : ,C , C++ ,
.h, .h.

, UNIX .( ) ..
( ). , google-awesome-project/src/base/logging.h :

#include "base/logging.h"

, dir/foo.cc dir/foo_test.cc dir2/foo2.h , foo.cc


:

1. dir2/foo2.h ( , )

2. C

3. C++

4. .h

5. .h

dir2/foo2.h dir/foo.cc dir/foo_test.cc

dir/foo.cc dir2/foo2.h ( base/basictypes_unittest.cc base/


basictypes.h), .

(symbols) include (forward


declarations) bar.h , foo.h bar.h,
bar.h, foo.h bar.h symbol. cc
cc foo.cc foo.h

, google-awesome-project/src/foo/internal/fooserver.cc :

#include "foo/public/fooserver.h" //

(continues on next page)

8 Chapter 2. C++ -
Google

(continued from previous page)

#include <sys/types.h>
#include <unistd.h>

#include <hash_map>
#include <vector>

#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"

system-specific conditional includes


includes

#include "foo/public/fooserver.h"

#include "base/port.h" // For LANG_CXX11.

#ifdef LANG_CXX11
#include <initializer_list>
#endif // LANG_CXX11

2.2.6 (YuleFox)

1. ;

2. ;

3. ;

4. -inl.h ( :D);

5. ( ,
);

6. . .. , , ,
, , (
:D) , , ,
, .

2.2.7 acgtyrant

1. #includes .inc

2. Google -inl.h

2.2. 1. 9
Google

3. incomplete type

4.
.cc

5. #include ,C , C++ , .h .h

2.3 2.

2.3.1 2.1.

Tip: .cc static . ,


. using using-directive inline namespace

, , .

(YuleFox : ),
.

, Foo, .
, project1::Foo project2::Foo
.

namespace X {
inline namespace Y {
void foo();
} // namespace Y
} // namespace X

X::Y::foo() X::foo() ABI

10 Chapter 2. C++ -
Google

C++ (One Definition Rule (ODR)).

• , gflags / ,
, :

// .h
namespace mynamespace {

//
//
class MyClass {
public:
...
void Foo();
};

} // namespace mynamespace

// .cc
namespace mynamespace {

//
void MyClass::Foo() {
...
}

} // namespace mynamespace

.cc , , gflags using

#include "a.h"

DEFINE_FLAG(bool, someflag, false, "dummy flag");

namespace a {

...code for a... //

} // namespace a

2.3. 2. 11
Google

• std , . std
, . , .

• using

//
using namespace foo;


API

// .cc
namespace baz = ::foo::bar::baz;

// .h
namespace librarian {
namespace impl { //
namespace sidetable = ::pipeline_diagnostics::sidetable;
} // namespace impl

inline void my_inline_function() {


//
namespace baz = ::foo::bar::baz;
...
}
} // namespace librarian

2.3.2 2.2.

Tip: .cc
static .h

static

.cc
.h

namespace :

12 Chapter 2. C++ -
Google

namespace {
...
} // namespace

2.3.3 2.3.

Tip: , .

, ,
.

,
.

, , .
, . , .
, 2.1.
myproject/foo_bar.h ,

namespace myproject {
namespace foo_bar {
void Function1();
void Function2();
} // namespace foo_bar
} // namespace myproject

namespace myproject {
class FooBar {
public:
static void Function1();
static void Function2();
};
} // namespace myproject

,
; . ,

2.3. 2. 13
Google

, .cc , 2.1.
static ( static int Foo() {...}) .

2.3.4 2.4.

Tip: , .

C++ . ,
. , .
, :

int i;
i = f(); //

int j = g(); //

vector<int> v;
v.push_back(1); //
v.push_back(2);

vector<int> v = {1, 2}; // v

if, while for


:

while (const char* p = strchr(str, '/')) str = p + 1;

Warning: , , ,
. .

//
for (int i = 0; i < 1000000; ++i) {
Foo f; // 1000000 !
f.DoSomething(i);
}

Foo f; // 1
for (int i = 0; i < 1000000; ++i) {
(continues on next page)

14 Chapter 2. C++ -
Google

(continued from previous page)

f.DoSomething(i);
}

2.3.5 2.5.

Tip: POD POD

bug constexpr

(POD : Plain Old Data): int, char float, POD

C++
bug. POD
getenv() getpid()

Note: Xris :

(unspecified behaviour)

main() exit()

string

quick_exit() exit()
atexit() handlers. quick_exit()
handler log _at_quick_exit(). exit()
quick_exit() handler,

POD vector ( C ) string (


const char [])

class main() pthread_once()


raw

Note: Yang.Y :

2.3. 2. 15
Google

, : , , ,
.

2.3.6 (YuleFox)

1. cc , , using ;

2. , , public;

3. , , ;

4. ( ) class ( STL ),
bug.

5. , , , , / .

2.3.7 acgtyrant

1. using using-directive using using-declaration

2. C static C++

3.
locality

4.

2.4 3.

C++ . , . .

2.4.1 3.1.

, .

• .

• const , .

16 Chapter 2. C++ -
Google

• , .
, .

• ( ) ( )
,

• , , , bool
IsValid() , .

• , , ,
.

. , . ,
Init() .

, . (non-trivial)
, Init() . Avoid Init() methods on objects with no other states
that affect which public methods may be called ( ).

2.4.2 3.2.

. , explicit .

( ) ( ) ,
, int double .

, .
, ( operator bool()).
, ( ) .

explicit ( C++11 ) ,
, cast. , C++11
:

class Foo {
explicit Foo(int x, double y);
...
};

void Func(Foo f);

Func({42, 3.14}); // Error

, explicit .

2.4. 3. 17
Google

• , ,
.

• .

• , .

• . , ,
.

• , ,
.

• .

• explicit ,
, explicit .

• , .

• , ,
.

, explicit . ,
explicit, .
, . .

explicit. std::initializer_list
explicit, ( MyType m = {1, 2};).

2.4.3 3.3.

, / . , .

,
, . ,
. string .

,
( ). std::unique_ptr<int>
. , .

/ . , .

18 Chapter 2. C++ -
Google

, API ,
. , , , ,
. , .
API , .

/ , Clone(), CopyFrom() or
Swap(), , , = default.
, . ,
, , .

. .

, , . (Registerer),
(Cleanup), (Mutex)
. / , .
, .

, , . ,
. , ,
.

/ . ,
, . ,
, . , ,
( ) . ,
, .

/ , . ,
/ .

class Foo {
public:
Foo(Foo&& other) : field_(other.field) {}
// , , .

private:
Field field_;
};

, /
( ). , public virtual
Clone() protected .

/ , public = delete .

2.4. 3. 19
Google

// MyClass is neither copyable nor movable.


MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;

2.4.4 3.4. VS.

struct, class.

C++ struct class . ,


.

struct , , ,
. , . , , Initialize(),
Reset(), Validate() , .

, class . , class.

STL , class struct.

: .

2.4.5 3.5.

(YuleFox : GoF <<Design Patterns>> )


. , public .

, . C++ , :
, ; , .

. ,
. , API. API
, .

, , .
, . ,
.

public . , .

20 Chapter 2. C++ -
Google

. . ( is-a , YuleFox : has-a


) : Bar Foo, Bar Foo.

, virtual. , .

, protected . , .

, override, ( ) final .
( C++11) virtual . , ,
override, final virtual . override final
, , . ,
, , .

2.4.6 3.6.

. :
; Interface .

. .

( ), .

. ,
, .

, . ,
Interface .

, Windows .

2.4.7 3.7.

, Interface ( ).

, :

• ( =0 ) ( ).

• .

• . , , protected.

2.4. 3. 21
Google

• , Interface .

, . ,
( 1 , ). Stroustrup
The C++ Programming Language, 3rd edition 12.4 .

Interface .
. , Java , .

Interface , . , .

, Interface , , Interface
.

2.4.8 3.8.

, . .

C++ operator ,
. operator operator"" , ,
operator bool().

, .
( ==, <, =, <<),
, .

, .

• , , ,
, Bug.

• , .

• , .

• , .

• grep , C++
.

• , . : foo <
bar , &foo < &bar .

22 Chapter 2. C++ -
Google

• . , & ,
. &&, || ,
.

• , , .
, ,
.

• C++ .

, . ,
| , shell .

. ,
, .cc . ,
. , ,
. , ,
. , <, , ,< >
true.

. ,
. a < b b < a ,
.

. , ==, =, << Equals(), CopyFrom()


PrintTo(). , . ,
, std::set , <.

&&, ||, , &. operator"", , .

. = .
<< . , .

2.4.9 3.9.

private, static const ( ).


, Google Test protected.

2.4.10 3.10.

, public .

public: , protected:, private:. .

2.4. 3. 23
Google

, , : ( typedef, using
), , , , , , , .

. ,
. .

2.4.11 (YuleFox)

1. ;

2. , , ,
;

3. , explicit;

4. , , private ;

5. struct;

6. > > > , virtual ,


;

7. , , , ;

8. Interface , , ,
, , , , protected;

9. , , , ;

10. ;

11. : public -> protected -> private;

12. , , ;

2.5 4.

2.5.1 4.1.

C++ / .
.

C/C++ , , .
const , / .
std::optional const
/

24 Chapter 2. C++ -
Google

const const
const
.

. ,
, , .

. / ( ) . ,
, .

2.5.2 4.2.

, .

, . 40 ,
.

, , , bug.
, .

, . : /
, , .

2.5.3 4.3.

const.

C , , , int foo(int *pval). C++ ,


: int foo(int &val).

(*pval)++ .
. .

, .

, const:

void Foo(const string &in, string *out);

2.5. 4. 25
Google

Google Code : const , .


const , const , , swap().

, const T* const T& . :

• .

• .

, const T&. const T* .


const T*, , .

2.5.4 4.4.

, ,
. .

const string& , const char*


:

class MyClass {
public:
void Analyze(const string &text);
void Analyze(const char *text, size_t textlen);
};

, . ,
.

(acgtyrant ), C++
, . , ,
.

, . , AppendString()
AppendInt() , Append().
, std::vector .

2.5.5 4.5.

26 Chapter 2. C++ -
Google

, .
. ,
.

, .
, . , ,
, .

,
.

,
.

, . ,
, .

, . .

, , .
, . ( , void f(int n =
counter++); .)

, , .
, .

2.5.6 4.6.

( ) .

C++ . . :

int foo(int x);

C++11 . auto , .
:

auto foo(int x) -> int;

. int , . ,
, .

2.5. 4. 27
Google

Lambda . ,
Lambda , . ,
.

, , ,
. :

template <class T, class U> auto add(T t, U u) -> decltype(t + u);

template <class T, class U> decltype(declval<T&>() + declval<U&>()) add(T t, U u);

, C Java ,
.

, .
. , .

, , .
( Lambda )
. , ,
.

2.6 5. Google

Google / C++ , C++


.

2.6.1 5.1.

>

, .

>

. ,
. , .
, .

* -> .
, . std::unique_ptr C++11 ,
; std::unique_ptr , .
std::unique_ptr , move . std::shared_ptr

28 Chapter 2. C++ -
Google

, , ; ,
, .

>

• , .

• , , .

• ,
.

• , , .

• , , .

• const , , .

>

• .
, API , , ,
.

• ,
.

• API , .

• , .

• std::unique_ptr C++11 move , ,


.

• , , .

• , .

• ( ), .

• .

>

, . ,
, . std::unique_ptr
,

std::unique_ptr<Foo> FooFactory();
void FooConsumer(std::unique_ptr<Foo> ptr);

, . ,
, std::shared_ptr<const Foo> ,
. , std::shared_ptr .

std::auto_ptr, std::unique_ptr .

2.6. 5. Google 29
Google

2.6.2 5.2. Cpplint

>

cpplint.py .

>

cpplint.py , . , ,
. // NOLINT, // NOLINTNEXTLINE,
.

cpplint.py. ,
cpplint.py.

2.6.3 acgtyrant

1. , .

2. Rust Ownership C++ .

3. scoped_ptr auto_ptr . shared_ptr uniqued_ptr .

4. , , , .

5. Arch Linux , AUR cpplint .

2.7 6. C++

2.7.1 6.1.

Tip: const.

C , , , int foo(int *pval).


C++ , : int foo(int &val).

(*pval)++ . .
, NULL .

, .

, const:

30 Chapter 2. C++ -
Google

void Foo(const string &in, string *out);

Google Code : const , .


const , const swap().

const T* const T&

• null

const T&. const T*


const T*,

2.7.2 6.2.

Tip: . std::forward.

, . ,
void f(string&& s); .

( )
. , v1 vector<string>, auto v2(std::move(v1))
, .

,
.

, ,
.

, std::unique_ptr, std::move .

( C++11 ), . ,
.

, std::forward .
std::move .

2.7.3 6.3.

2.7. 6. C++ 31
Google

Tip: call site

const string& , const char*


:

class MyClass {
public:
void Analyze(const string &text);
void Analyze(const char *text, size_t textlen);
};

, . ,
.

acgtyrant
C++

, AppendString()
AppendInt() Append().

2.7.4 6.4.

Tip:

function signature

call site acgtyrant

32 Chapter 2. C++ -
Google

acgtyrant

.cc

// AlphaNum
string StrCat(const AlphaNum &a,
const AlphaNum &b = gEmptyAlphaNum,
const AlphaNum &c = gEmptyAlphaNum,
const AlphaNum &d = gEmptyAlphaNum);

2.7.5 6.5. alloca()

Tip: alloca().

. alloca() .

alloca() C++ . ,
, bugs: ,
.

allocator std::vector std::unique_ptr<T[]>.

2.7.6 6.6.

Tip: .

, .
FooBuilder Foo , FooBuilder Foo ,
. , .

2.7. 6. C++ 33
Google

( ) . , public,
, . ,
.

2.7.7 6.7.

Tip: C++ .

• failures
acgtyrant error code, int

• C++ Python, Java C++

• C++

• acgtyrant factory function,


C++ Init() ,

• throw
f()
g(), g() h(), h f g,

• RAII . .
, ,
. ( ). ,
, .

, . ,
. ,
. Google C++ ,
.

34 Chapter 2. C++ -
Google

Google ,
. , . , ,
.

, . Google
, , Google
. .

Windows , .

(YuleFox : , , , C++
, Google , , ,
, )

2.7.8 6.8.

TODO

Tip: RTTI.

RTTI C++ . typeid dynamic_cast


.

RTTI ( ) .
, , .

RTTI . ,
. RTTI .

RTTI . :

bool Base::Equal(Base* other) = 0;


bool Derived::Equal(Base* other) {
Derived* that = dynamic_cast<Derived*>(other);
if (that == NULL)
return false;
...
}

. ,
.

RTTI . switch
. , .

2.7. 6. C++ 35
Google

RTTI , .
RTTI, . , RTTI .
,
:

. .

, ,
. .

, dy-
namic_cast. , dynamic_cast .

, . :

if (typeid(*data) == typeid(D1)) {
...
} else if (typeid(*data) == typeid(D2)) {
...
} else if (typeid(*data) == typeid(D3)) {
...

, . , ,
.

RTTI . RTTI ,
. , .

2.7.9 6.9.

Tip: C++ , static_cast<>(). int y = (int)x int y = int(x)


;

C++ C , .

C ; ( (int)3.5),
( (int)"hello"). , C++ .

C . C++ .

36 Chapter 2. C++ -
Google

• static_cast C ,
.

• const_cast const .

• reinterpret_cast .
.

dynamic_cast 6.8. .

2.7.10 6.10.

Tip: .

printf() scanf().

, . (
gcc printf ). .

pread() . printf ,
( %.*s) .
(%1s), .

, . printf .

, . .

, . (Only One Way):


I/O , I/O . ,
printf + read/write. ,
. , .

, .
. . . ,
: , . :

cout << this; //


cout << *this; //

<< , . .

printf , , . ,
, ?

2.7. 6. C++ 37
Google

cerr << "Error connecting to '" << foo->bar()->hostname.first


<< ":" << foo->bar()->hostname.second << ": " <<␣
,→strerror(errno);

fprintf(stderr, "Error connecting to '%s:%u: %s",


foo->bar()->hostname.first, foo->bar()->hostname.second,
strerror(errno));

, , , ? ,
, .

, , .
, printf + read/write.

2.7.11 6.11.

Tip: (++i) , .

(++i i++) (--i i--) ,


( ).

, (++i) (i++) . (
) i . i ,
. , ?

C , , , for .
, , (i) (++) .

( ), . , ( ).

2.7.12 6.12. const

Tip: const. C++11 constexpr

38 Chapter 2. C++ -
Google

const ( const int foo


). const ( class Foo {
int Bar(char c) const; };).

. , ,
. ,
. , .

const : const , const


( const_cast ), .

const , , ; .
, const:

• , const.

• const. const. ,
const , const const.

• , const.

, const. const int * const * const x; ,


x. : const int** x
.

mutable , , .

const :

int const *foo , const int* foo,


: const . ,
. const ,
(const) (int) .

, const . ! (Yang.Y :
const , , , .)

2.7.13 6.13. constexpr

Tip: C++11 constexpr

constexpr
constexpr, constexpr

2.7. 6. C++ 39
Google

constexpr

constexpr con-
stexpr

constexpr C++ constexpr


constexpr
constexpr

2.7.14 6.14.

Tip: C++ , int. , <stdint.h>


, int16_t. 2^31 (2GiB), 64 int64_t.
int

C++ . short 16 , int 32 , long 32 , long


long 64 .

C++ .

<stdint.h> int16_t, uint32_t, int64_t ,


short, unsigned long long . C , int. ,
size_t ptrdiff_t.

, int, .
int. int 32 , 32 . 64 ,
int64_t uint64_t.

, int64_t.

uint32_t , ,
. , . ,
.

size

40 Chapter 2. C++ -
Google

acgtyrant integer promotions, int unsigned int


unsigned int

, , .
. , C , bug . :

for (unsigned int i = foo.Length()-1; i >= 0; --i) ...

! gcc bug , . bug


. C
.

, , !

2.7.15 6.15. 64

Tip: 64 32 . , , :

• , printf() 32 64 . C99
. , MSVC 7.1 , ,
( inttypes.h ):

// printf macros for size_t, in the style of inttypes.h


#ifdef _LP64
#define __PRIS_PREFIX "z"
#else
#define __PRIS_PREFIX
#endif

// Use these macros after a % in a printf format string


// to get correct 32/64 bit behavior, like this:
// size_t size = records.size();
// printf("%"PRIuS"\n", size);
#define PRIdS __PRIS_PREFIX "d"
#define PRIxS __PRIS_PREFIX "x"
#define PRIuS __PRIS_PREFIX "u"
#define PRIXS __PRIS_PREFIX "X"
#define PRIoS __PRIS_PREFIX "o"

2.7. 6. C++ 41
Google

void * ( %lx %p
)
int64_t %qd, %lld %"PRId64"
uint64_t %qu, %llu, %"PRIu64",
%llx %"PRIx64"
size_t %u %"PRIuS", %"PRIxS" C99
%zu
ptrdiff_t %d %"PRIdS" C99
%zd

PRI* . ,
. PRI* % .
, printf("x = %30"PRIuS"\n", x) 32 Linux printf("x = %30"
"u" "\n", x), printf("x = %30u\n", x) (Yang.Y : MSVC
6.0 , VC 6 ).

• sizeof(void *) != sizeof(int). intptr_t.

• , (Yang.Y : -
). 64 , int64_t/uint64_t
/ , 8 . 32 64 ,
. . gcc
__attribute__((packed)). MSVC #pragma pack() __declspec(align()) (Yule-
Fox , ).

• 64 LL ULL , :

int64_t my_value = 0x123456789LL;


uint64_t my_mask = 3ULL << 48;

• 32 64 , #ifdef _LP64 32/64


. ( , , )

2.7.16 6.16.

Tip: , , .

. , .

, C++ , C . ,
. const . .
, , (#define ).

, ( ) (
# , ## ). , .

42 Chapter 2. C++ -
Google

; , :

• .h .

• #define, #undef.

• #undef

• C++ , .

• ##

2.7.17 6.17. 0, nullptr NULL

Tip: 0, 0.0, nullptr NULL, ( ) '\0'.

0, 0.0, .

( ), 0, NULL nullptr. C++11 nullptr; C++03 NULL,


C++ NULL
sizeof(NULL) sizeof(0)

( ) '\0', .

2.7.18 6.18. sizeof

Tip: sizeof(varname) sizeof(type).

sizeof(varname) . sizeof(type)

Struct data;
Struct data; memset(&data, 0, sizeof(data));

Warning:

memset(&data, 0, sizeof(Struct));

if (raw_size < sizeof(int)) {


LOG(ERROR) << "compressed record not big enough for count: " << raw_size;
return false;
}

2.7. 6. C++ 43
Google

2.7.19 6.19. auto

Tip: auto

C++11 auto,
auto

vector<string> v;
...
auto s1 = v[0]; // v[0]
const auto& s2 = v[0]; // s2 v[0]

C++

sparse_hash_map<string, int>::iterator iter = m.find(val);

auto iter = m.find(val);

auto

diagnostics::ErrorStatus* status = new diagnostics::ErrorStatus("xyz");

auto,

auto i = x.Lookup(key);

auto const auto&

auto C++11

auto x(3); //
auto y{3}; //

x int, y std::initializer_list<int>.
acgtyrant normally-invisible proxy types, C++ Why
is vector<bool> not a STL container?

44 Chapter 2. C++ -
Google

auto,
API

auto
auto

auto C++11 trailing return type


lambda

2.7.20 6.20.

Tip:

C++03 aggregate types

struct Point { int x; int y; };


Point p = {1, 2};

C++11

// Vector
vector<string> v{"foo", "bar"};

//
//
vector<string> v = {"foo", "bar"};

// new
auto p = new vector<string>{"foo", "bar"};

// map pair,
map<int, string> m = {{1, "one"}, {2, "2"}};

//
vector<int> test_function() { return {1, 2, 3}; }

//
for (int i : {-1, -2, -3}) {}

//
void TestFunction2(vector<int> v) {}
TestFunction2({1, 2, 3});

2.7. 6. C++ 45
Google

std::initializer_list<T>

class MyType {
public:
// std::initializer_list init
//
MyType(std::initializer_list<int> init_list) {
for (int i : init_list) append(i);
}
MyType& operator=(std::initializer_list<int> init_list) {
clear();
for (int i : init_list) append(i);
}
};
MyType m{2, 3, 5, 7};

std::initializer_list<T>

double d{1.23};
// MyOtherType std::initializer_list
//
class MyOtherType {
public:
explicit MyOtherType(string);
MyOtherType(int, string);
};
MyOtherType m = {1, "b"};
// explict `= {}`
MyOtherType m{"b"};

auto

Warning:

auto d = {1.23}; // d std::initializer_list<double>

auto d = double{1.23}; // -- d double, std::initializer_list.

9.7. .

2.7.21 6.21. Lambda

46 Chapter 2. C++ -
Google

Tip: lambda lambda

Lambda

std::sort(v.begin(), v.end(), [](int x, int y) {


return Weight(x) < Weight(y);
});

C++11 Lambdas, poly-


morphic wrapper std::function.

• STL Lambdas

• Lambdas, std::functions std::bind general purpose callback


mechanism

• Lambdas

• Lambdas

• format lambda

• [=](int x) {return x + n;},


[n](int x) {return x + n;} n

• acgtyrant lambda

• lambd auto.

2.7.22 6.22.

Tip:

c++ ,

, Google
Test, std::tuple, std::function Boost.Spirit.

2.7. 6. C++ 47
Google

• c++ , .
, debug

• : , ,
. .

• (Visual Assist X, Refactor for C++ ) .


, ,
AST .
, .

• , .
, ,

• , .
. c++
.
, , , , SFINAE, sizeof
trick , , ,

• , , .
, ,
. .
, .
. ,
,

2.7.23 6.23. Boost

Tip: Boost .

Boost , , C++ .

Boost , , C++ , ,
,

Boost , ,
.

48 Chapter 2. C++ -
Google

, Boost
. :

• Call Traits : boost/call_traits.hpp

• Compressed Pair : boost/compressed_pair.hpp

• <The Boost Graph Library (BGL) : boost/graph, except serialization


(adj_list_serialize.hpp) and parallel/distributed algorithms and data struc-
tures(boost/graph/parallel/* and boost/graph/distributed/*)

• Property Map : boost/property_map.hpp

• The part of Iterator that deals with defining iterators: boost/iterator/


iterator_adaptor.hpp, boost/iterator/iterator_facade.hpp, and boost/
function_output_iterator.hpp

• The part of Polygon that deals with Voronoi diagram construction and doesn t de-
pend on the rest of Polygon: boost/polygon/voronoi_builder.hpp, boost/polygon/
voronoi_diagram.hpp, and boost/polygon/voronoi_geometry_type.hpp

• Bimap : boost/bimap

• Statistical Distributions and Functions : boost/math/distributions

• Multi-index : boost/multi_index

• Heap : boost/heap

• The flat containers from Container: boost/container/flat_map, and boost/


container/flat_set

Boost , .

C++ 11

• Pointer Container : boost/ptr_container, std::unique_ptr

• Array : boost/array.hpp, std::array

2.7.24 6.24. C++11

Tip: C++11 C++0x C++11

C++11 ‘ <https://en.wikipedia.org/wiki/C%2B%2B11>‘_

C++11 C++
C++

2.7. 6. C++ 49
Google

C++11 1300 vs 800

6.23. Boost C++11

C++11 C++11

• auto foo() -> int int foo().

• <ratio>,

• <cfenv> <fenv.h>

• lambda

2.7.25 acgtyrant

1. void a() void


a(int b = 0),
int

2.

3.

4. friend
friend .cc

5.

6.

7. C++

8. const

9.

10. auto

11. Should the trailing return type syntax style become the default for new C++11 programs?
auto

50 Chapter 2. C++ -
Google

2.8 7.

.
: , , , , , , .
.

, , , ,
.

2.8.1 7.1.

, , ; .

, , .
, .

int price_count_reader; //
int num_errors; // "num"
int num_dns_connections; // "DNS"

int n; // .
int nerr; // .
int n_comp_conns; // .
int wgc_connections; // .
int pc_reader; // "pc" .
int cstmr_id; // .

, , i T .

: ,
.

2.8.2 7.2.

, (_) (-), . , _ .

• my_useful_class.cc

• my-useful-class.cc

• myusefulclass.cc

2.8. 7. 51
Google

• myusefulclass_test.cc // _unittest _regtest .

C++ .cc , .h . .inc , .

/usr/include (Yang.Y : ), db.h.

. http_server_logs.h logs.h . ,
foo_bar.h foo_bar.cc, FooBar.

.h . , .h .

2.8.3 7.3.

, : MyExcitingClass, MyExcitingEnum.

, , (typedef), , ,
, , . :

//
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...

//
typedef hash_map<UrlTableProperties *, string> PropertiesMap;

// using
using PropertiesMap = hash_map<UrlTableProperties *, string>;

//
enum UrlTableErrors { ...

2.8.4 7.4.

( ) , . ,
, : a_local_variable, a_struct_data_member, a_class_data_member_.

52 Chapter 2. C++ -
Google

string table_name; // - .
string tablename; // - .

string tableName; // -

, , .

class TableInfo {
...
private:
string table_name_; // - .
string tablename_; // .
static Pool<TableInfo>* pool_; // .
};

, , :

struct UrlTableProperties {
string name;
int num_entries;
static Pool<UrlTableProperties>* pool;
};

, vs. .

2.8.5 7.5.

constexpr const , , k ,
. :

const int kDaysInAWeek = 7;

( , ) .
, , . ,
.

2.8. 7. 53
Google

2.8.6 7.6.

, : MyExcitingFunction(),
MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable().

, ( ), .
, ( , StartRpc() StartRPC()).

AddTableEntry()
DeleteUrl()
OpenFileOrDie()

( , API
, , ,
.)

. , .
int count() void set_count(int count).

2.8.7 7.7.

. .
.

. ,
.

. ,
.

. ,
. , std .
(websearch::index, websearch::index_util) (
websearch::util).

internal , internal (
, ). ,
( frobber.h, websearch::index::frobber_internal).

2.8.8 7.8.

: kEnumName ENUM_NAME.

54 Chapter 2. C++ -
Google

. . UrlTableErrors (
AlternateUrlTableErrors) , .

enum UrlTableErrors {
kOK = 0,
kErrorOutOfMemory,
kErrorMalformedInput,
};
enum AlternateUrlTableErrors {
OK = 0,
OUT_OF_MEMORY = 1,
MALFORMED_INPUT = 2,
};

2009 1 , . ,
. , . .
, .

2.8.9 7.9.

, ? , : MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

; . , , :

#define ROUND(x) ...


#define PI_ROUNDED 3.0

2.8.10 7.10.

C/C++ , .

bigopen(): , open()

uint: typedef

bigpos: struct class, pos

sparse_hash_map: STL ; STL

LONGLONG_MAX: , INT_MAX

2.8. 7. 55
Google

2.8.11 acgtyrant

1. Google , QueryResult,
query_result, ; , , ,
TextQuery::TextQuery(std::string word) : word_(word) {} , word_
.

2.9 8.

, . .
: , . ,
.

, . ,
!

2.9.1 8.1.

// /* */, .

// /* */ ; // . .

2.9.2 8.2.

. , , ,
, . .

. .( , Apache 2.0, BSD, LGPL, GPL)

, .

.h , ,
. , ,
.

56 Chapter 2. C++ -
Google

.h .cc , .

2.9.3 8.3.

, , .

// Iterates over the contents of a GargantuanTable.


// Example:
// GargantuanTableIterator* iter = table->NewIterator();
// for (iter->Seek("foo"); !iter->done(); iter->Next()) {
// process(iter->key(), iter->value());
// }
// delete iter;
class GargantuanTableIterator {
...
};

,
. , . ,
.

, .

( .h .cc ), ,
, .

2.9.4 8.4.

; .

, .
( , ). ( Opens the file ) ( Open
the file ); , . , .
.

• .

• : , .

2.9. 8. 57
Google

• .

• .

• .

• , ?

// Returns an iterator for this table. It is the client's


// responsibility to delete the iterator when it is done with it,
// and it must not use the iterator once the GargantuanTable object
// on which the iterator was created has been deleted.
//
// The iterator is initially positioned at the beginning of the table.
//
// This method is equivalent to:
// Iterator* iter = table->NewIterator();
// iter->Seek("");
// return iter;
// If you are going to immediately seek to another place in the
// returned iterator, it will be faster to use NewIterator()
// and avoid the extra seek.
Iterator* GetIterator() const;

, . false ,
:

// Returns true if the table cannot hold any more entries.


bool IsTableFull();

, , .
, , .

/ , / ,
. ( , )
. , . .

, . ,
, , . ,
.

.h . ,
.

58 Chapter 2. C++ -
Google

2.9.5 8.5.

. , .

( ) . ( ,
, ) , . ,
, .

, NULL -1 , . :

private:
// Used to bounds-check table accesses. -1 means
// that we don't yet know how many entries the table has.
int num_total_entries_;

, , . :

// The total number of tests cases that we run through in this regression test.
const int kNumTestCases = 6;

2.9.6 8.6.

, , , .

. :

// Divide result by two, taking into account that x


// contains the carry from the add.
for (int i = 0; i < result->size(); i++) {
x = (x << 8) + (*result)[i];
(*result)[i] = x >> 1;
x &= 1;
}

2.9. 8. 59
Google

. . :

// If we have enough memory, mmap the data portion too.


mmap_budget = max<int64>(0, mmap_budget - index_->length());
if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))
return; // Error already logged.

, , .

, :

DoSomething(); // Comment here so the comments line up.


DoSomethingElseThatIsLonger(); // Two spaces between the code and the comment.
{ // One space before comment when opening a new scope is allowed,
// thus the comment lines up with the following comments and code.
DoSomethingElse(); // Two spaces before line comments normally.
}
std::vector<string> list{
// Comments in braced lists describe the next element...
"First item",
// .. and should be aligned appropriately.
"Second item"};
DoSomething(); /* For trailing block comments, one space is fine. */

, :

• , , ,
, .

• , bool enum ,
.

• , ,
. , ,
. , . ,
, , .

• .

• , .

// What are these arguments?


const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);

60 Chapter 2. C++ -
Google

ProductOptions options;
options.set_precision_decimals(7);
options.set_use_cache(ProductOptions::kDontUseCache);
const DecimalNumber product =
CalculateProduct(values, options, /*completion_callback=*/nullptr);

, , C++
. C++ , / :

, .

// Find the element in the vector. <-- : !


auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
Process(element);
}

// Process "element" unless it was already processed.


auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
Process(element);
}

. :

if (!IsAlreadyProcessed(element)) {
Process(element);
}

2.9.7 8.7. ,

, ; .

. ,
. , , , .

2.9. 8. 61
Google

, . ,
.

2.9.8 8.8. TODO

, , TODO .

TODO TODO, , , bug ID,


TODO issue. ( )
TODO . TODO , TODO
, .

// TODO([email protected]): Use a "*" here for concatenation operator.


// TODO(Zeke) change this to use relations.
// TODO(bug 12345): remove the "Last visitors" feature

TODO , Fix by November 2005 ),


( Remove this code when all clients can handle XML responses. ).

2.9.9 8.9.

DEPRECATED comments .

DEPRECATED , . ,
.

DEPRECATED , , .

, . C++ ,
, .

DEPRECATED , callsites ,
.

, . ,
.

2.9.10 (YuleFox)

1. , C++ coders , C coders ,


;

2. , ;

3. , , ;

62 Chapter 2. C++ -
Google

4. Chinese coders , , it is a problem, ,


,

5. , . (
), UNIX/LINUX tab space, space;

6. TODO , , ,
, , .

2.10 9.

, ,
. , ,
, .

, emacs .

2.10.1 9.1.

80.

, , .

. ,
. , 80 .
?

. 80 60 ;
, .

80 .

, 80 , .
, URL 80 .

#include 80 .

2.10.2 9.2. ASCII

ASCII , UTF-8 .

2.10. 9. 63
Google

, , ASCII .
. , ,
ASCII ; ( ) ASCII . ,
UTF-8 , UTF-8 .

, "\xEF\xBB\xBF",
u8"\uFEFF", Unicode , UTF-8
, .

(Yang.Y : "\xEF\xBB\xBF" UTF-8 with BOM )

u8 uXXXX UTF-8. UTF-8


, UTF-8, .

C++11 char16_t char32_t, UTF-8 , wchar_t ,


Windows API, wchar_t.

2.10.3 9.3.

, 2 .

. . .

2.10.4 9.4.

, , ,
.

ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {


DoSomething();
...
}

, :

ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,


Type par_name3) {
DoSomething();
(continues on next page)

64 Chapter 2. C++ -
Google

(continued from previous page)

...
}

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
Type par_name1, // 4 space indent
Type par_name2,
Type par_name3) {
DoSomething(); // 2 space indent
...
}

• .

• , .

• , .

• , .

• .

• .

• .

• , .

• , .

• .

• .

• 2 .

• 4 .

, , :

class Foo {
public:
Foo(Foo&&);
Foo(const Foo&);
Foo& operator=(Foo&&);
Foo& operator=(const Foo&);
};

, :

2.10. 9. 65
Google

class Shape {
public:
virtual void Rotate(double radians) = 0;
};

class Circle : public Shape {


public:
void Rotate(double radians) override;
};

void Circle::Rotate(double /*radians*/) {}

// - , .
void Circle::Rotate(double) {}

, , , :

MUST_USE_RESULT bool IsOK();

2.10.5 9.5. Lambda

Lambda ; , .

, & .

int x = 0;
auto add_to_x = [&x](int n) { x += n; };

lambda .

std::set<int> blacklist = {7, 8, 9};


std::vector<int> digits = {3, 9, 1, 8, 4, 7, 1};
digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) {
return blacklist.find(i) != blacklist.end();
}),
digits.end());

2.10.6 9.6.

66 Chapter 2. C++ -
Google

, , .
, , .

bool retval = DoSomething(argument1, argument2, argument3);

, , ,

bool retval = DoSomething(averyveryveryverylongargument1,


argument2, argument3);

if (...) {
...
...
if (...) {
DoSomething(
argument1, argument2, // 4
argument3, argument4);
}

, .
, , . , , ,

, , ,

int my_heuristic = scores[x] * y + bases[x];


bool retval = DoSomething(my_heuristic, x, y, z);

bool retval = DoSomething(scores[x] * y + bases[x], // Score heuristic.


x, y, z);

, , .
.

, ,

// 3x3 widget.
my_widget.Transform(x1, x2, x3,
y1, y2, y3,
z1, z2, z3);

2.10. 9. 67
Google

2.10.7 9.7.

, .

, , , {}
. , .

// .
return {foo, bar};
functioncall({foo, bar});
pair<int, int> p{foo, bar};

// .
SomeFunction(
{"assume a zero-length name before {"}, // { .
some_other_function_parameter);
SomeType variable{
some, other, values,
{"assume a zero-length name before {"}, // { .
SomeOtherType{
"Very long string requiring the surrounding breaks.", // ,
.
some, other values},
SomeOtherType{"Slightly shorter string", // .
some, other, values}};
SomeType variable{
"This is too long to fit all in one line"}; // , .
MyType m = { // , { .
superlongvariablename1,
superlongvariablename2,
{short, interior, list},
{interiorwrappinglist,
interiorwrappinglist2}};

2.10.8 9.8.

. if else .

. , .

68 Chapter 2. C++ -
Google

. , . ,
. , . , .

if (condition) { // .
... // 2 .
} else if (...) { // else if .
...
} else {
...
}

if ( condition ) { // -
... // 2 .
} else { // else if .
...
}

if . :

if(condition) // - IF .
if (condition){ // - { .
if(condition){ // .

if (condition) { // - IF { .

, . else :

if (x == kFoo) return new Foo();


if (x == kBar) return new Bar();

else :

// - ELSE IF
if (x) DoThis();
else DoThat();

, , ;
. if :

if (condition)
DoSomething(); // 2 .

if (condition) {
DoSomething(); // 2 .
(continues on next page)

2.10. 9. 69
Google

(continued from previous page)

if-else , :

// - IF ELSE .
if (condition) {
foo;
} else
bar;

// - ELSE IF .
if (condition)
foo;
else {
bar;
}

// , .
if (condition) {
foo;
} else {
bar;
}

2.10.9 9.9.

switch , cases . ,
. {} continue.

switch case , . ,
.

case , switch default ( case


, warning). default , assert:

switch (var) {
case 0: { // 2
... // 4
break;
}
case 1: {
(continues on next page)

70 Chapter 2. C++ -
Google

(continued from previous page)

...
break;
}
default: {
assert(false);
}
}

for (int i = 0; i < kSomeNumber; ++i)


printf("I love you\n");

for (int i = 0; i < kSomeNumber; ++i) {


printf("I take it back\n");
}

{} continue, .

while (condition) {
// .
}
for (int i = 0; i < kSomeNumber; ++i) {} // - .
while (condition) continue; // - contunue .

while (condition); // - while/loop .

2.10.10 9.10.

. / (*, &) .

x = *p;
p = &x;
x = r.y;
x = r->y;

• , .

• * & .

2.10. 9. 71
Google

, :

// , .
char *c;
const string &str;

// , .
char* c;
const string& str;

int x, *y; // - & *


char * c; // - *
const string & str; // - & .

, , , .

2.10.11 9.11.

, .

, (&&) :

if (this_one_thing > this_other_thing &&


a_third_thing == a_fourth_thing &&
yet_another && last_one) {
...
}

, (&&) . Google ,
. , . ,
, && ~, and compl.

2.10.12 9.12.

return .

x = expr return expr; .

return result; // , .
// , .
(continues on next page)

72 Chapter 2. C++ -
Google

(continued from previous page)

return (some_long_condition &&


another_condition);

return (value); // var = (value);


return(result); // return

2.10.13 9.13.

=, () {} .

=, () {},

int x = 3;
int x(3);
int x{3};
string name("Some Name");
string name = "Some Name";
string name{"Some Name"};

{...} std::initializer_list .
std::initializer_list, , .
std::initializer_list , .

vector<int> v(100, 1); // 100 1 .


vector<int> v{100, 1}; // 100 1 .

, , .

int pi(3.14); // - pi == 3.
int pi{3.14}; // : .

2.10.14 9.14.

, .

, .

2.10. 9. 73
Google

// -
if (lopsided_score) {
#if DISASTER_PENDING // -
DropEverything();
# if NOTIFY // - #
NotifyClient();
# endif
#endif
BackToNormal();
}

// -
if (lopsided_score) {
#if DISASTER_PENDING // - "#if"
DropEverything();
#endif // - "#endif"
BackToNormal();
}

2.10.15 9.15.

public:, protected:, private:, 1 .

( , ) :

class MyClass : public OtherClass {


public: //
MyClass(); //
explicit MyClass(int var);
~MyClass() {}

void SomeFunction();
void SomeFunctionThatDoesNothing() {
}

void set_some_var(int var) { some_var_ = var; }


int some_var() const { return some_var_; }

private:
bool SomeInternalFunction();

(continues on next page)

74 Chapter 2. C++ -
Google

(continued from previous page)

int some_var_;
int some_other_var_;
};

• 80 .

• public:, protected:, private: 1 .

• ( public) , . .

• .

• public , protected, private.

• .

2.10.16 9.16.

// :
MyClass::MyClass(int var) : some_var_(var) {
DoSomething();
}

// ,
// , 4
MyClass::MyClass(int var)
: some_var_(var), some_other_var_(var + 1) {
DoSomething();
}

// ,
//
MyClass::MyClass(int var)
: some_var_(var), // 4 space indent
some_other_var_(var + 1) { // lined up
DoSomething();
}

// } {
(continues on next page)

2.10. 9. 75
Google

(continued from previous page)

//
MyClass::MyClass(int var)
: some_var_(var) {}

2.10.17 9.17.

, :

namespace {

void foo() { // . .
...
}

} // namespace

namespace {

// , .
void foo() {
...
}

} // namespace

, .

namespace foo {
namespace bar {

2.10.18 9.18.

. .

76 Chapter 2. C++ -
Google

void f(bool b) { // .
...
int i = 0; // .
// .
// , .
int x[] = { 0 };
int x[] = {0};

// .
class Foo : public Bar {
public:
// ,
//
Foo(int b) : Bar(), baz_(b) {} // , .
void Reset() { baz_ = 0; } // .
...

. , .
, ; ). (Yang.Y
: , / , ,
IDE)

if (b) { // if .
} else { // else .
}
while (test) {} // .
switch (i) {
for (int i = 0; i < 5; ++i) {
switch ( i ) { // .
if ( test ) { // , . .
for ( int i = 0; i < 5; ++i ) {
for ( ; i < 5 ; ++i) { // ; , ; .
switch (i) {
case 1: // switch case .
...
case 2: break; // , .

2.10. 9. 77
Google

// .
x = 0;

// , .
// .
v = w * x + y / z;
v = w*x + y/z;
v = w * (x + z);

// .
x = -5;
++x;
if (x && !y)
...

// (< and >) , < , > ( .


vector<string> x;
y = static_cast<char*>(x);

// , .
vector<char *> x;

2.10.19 9.19.

: , . :
2 , , .

: , . ,
, . .

• .

• if-else .

78 Chapter 2. C++ -
Google

2.10.20 (YuleFox)

1. , , , ;

2. 80 , 22 , ;

3. ASCII , , UTF-8 ( UNIX/Linux , Windows


), , ,
;

4. UNIX/Linux , MSVC Tab ;

5. , , : , ;

6. , / / / ,
, ;

7. ./-> , */& , , ;

8. / , / / / / ;

9. = () , ;

10. return ();

11. / , .

12. UNIX/Linux (.cc ,


), , ,
; Windows .

2.10.21 acgtyrant

1. 80 , , .

2. Linux Locale , Windows.

3. Google if-else , , . Apple .

4. , int* a, b vs int *a, b, b


int * , , .

5. C++ Alternative operator representations,


.

6. Constructer Initializer List Initializer List ,


.

7. , ,
. , ;
, if (true) true.

8. void return , Google leveldb


; Is a blank return statement at the end of a function whos return type is void
necessary? , return; return ; cpplint ,
, .

2.10. 9. 79
Google

2.11 10.

. , .

2.11.1 10.1.

, . ,
. , .

2.11.2 10.2. Windows

Windows , Windows Microsoft .


, C++ .

Windows , :

• ( iNum). Google ,
.cc .

• Windows (YuleFox : , ), DWORD, HANDLE


. Windows API . , C++
, const TCHAR * LPCTSTR.

• Microsoft Visual C++ , 3 , (warnings)


(errors) .

• #pragma once; Google .


(Yang.Y : #ifndef SRC_DIR_BAR_H_, #define ).

• , , #pragma __declspec.
__declspec(dllimport) __declspec(dllexport) , ,
DLLIMPORT DLLEXPORT, .

, Windows :

• , COM ATL/WTL .
COM ATL/WTL / , .

• , ATL STL Visual C++ STL)


. ATL , _ATL_NO_EXCEPTIONS . STL
, , . ( STL,
).

80 Chapter 2. C++ -
Google

• , StdAfx.h precompile.h
. , ( precompile.cc ),
/FI .

• resource.h , .

2.12 11.

, .

, , . if ,
. (*) , .

, .
, ,
, , , .

, ; . !

2.12. 11. 81
Google

82 Chapter 2. C++ -
CHAPTER 3

Objective-C -

3.1 Google Objective-C Style Guide

2.36

Mike Pinkerton
Greg Miller
Dave MacLachlan

ewangke
Yang.Y

• Google Style Guide

• Google -

3.1.1

ewanke

style guide 7 vim HTML

ewangke at gmail.com 2011.03.27

83
Google

Yang.Y

Objective-C C/C++

• 2.36

3.1.2

Objective-C C
Mac OS X iPhone

Cocoa Mac OS X Objective-C


Mac OS X

Objective-C Google C++


Objective-C Google

• Apple s Cocoa Coding Guidelines

• Google s Open Source C++ Style Guide

Note: Google C++ Objective-C++

Mac OS X
Google

Google Google Toolbox for Mac project


GTM GTM

Objective-C Objective-C Objective-


C The Objective-C Programming Language

3.1.3

@interface

// Foo.h
// AwesomeProject
//
// Created by Greg Miller on 6/13/08.
// Copyright 2008 Google, Inc. All rights reserved.
//

(continues on next page)

84 Chapter 3. Objective-C -
Google

(continued from previous page)

#import <Foundation/Foundation.h>

// A sample class demonstrating good Objective-C style. All interfaces,


// categories, and protocols (read: all top-level declarations in a header)
// MUST be commented. Comments must also be adjacent to the object they're
// documenting.
//
// (no blank line between this comment and the interface)
@interface Foo : NSObject {
@private
NSString *bar_;
NSString *bam_;
}

// Returns an autoreleased instance of Foo. See -initWithBar: for details


// about |bar|.
+ (id)fooWithBar:(NSString *)bar;

// Designated initializer. |bar| is a thing that represents a thing that


// does a thing.
- (id)initWithBar:(NSString *)bar;

// Gets and sets |bar_|.


- (NSString *)bar;
- (void)setBar:(NSString *)bar;

// Does some work with |blah| and returns YES if the work was completed
// successfully, and NO otherwise.
- (BOOL)doWorkWithBlah:(NSString *)blah;

@end

@implementation
getters setters init dealloc

//
// Foo.m
// AwesomeProject
//
// Created by Greg Miller on 6/13/08.
// Copyright 2008 Google, Inc. All rights reserved.
//

(continues on next page)

3.1. Google Objective-C Style Guide 85


Google

(continued from previous page)

#import "Foo.h"

@implementation Foo

+ (id)fooWithBar:(NSString *)bar {
return [[[self alloc] initWithBar:bar] autorelease];
}

// Must always override super's designated initializer.


- (id)init {
return [self initWithBar:nil];
}

- (id)initWithBar:(NSString *)bar {
if ((self = [super init])) {
bar_ = [bar copy];
bam_ = [[NSString alloc] initWithFormat:@"hi %d", 3];
}
return self;
}

- (void)dealloc {
[bar_ release];
[bam_ release];
[super dealloc];
}

- (NSString *)bar {
return bar_;
}

- (void)setBar:(NSString *)bar {
[bar_ autorelease];
bar_ = [bar copy];
}

- (BOOL)doWorkWithBlah:(NSString *)blah {
// ...
return NO;
}

@end

86 Chapter 3. Objective-C -
Google

@interface @implementation @end @interface


}

3.2

3.2.1 vs.

Tip:

3.2.2

80

Objective-C 80

80

Xcode > Preferences > Text Editing > Show page guide

3.2.3

Tip:

• /+

- (void)doSomethingWithString:(NSString *)theString {
...
}

3.2. 87
Google

- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect
interval:(float)theInterval {
...
}

- (void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval {
...
}

3.2.4

Tip:

[myObject doFooWith:arg1 name:arg2 error:arg3];

[myObject doFooWith:arg1
name:arg2
error:arg3];

[myObject doFooWith:arg1 name:arg2 // some lines with >1 arg


error:arg3];

[myObject doFooWith:arg1
name:arg2 error:arg3];

[myObject doFooWith:arg1
name:arg2 // aligning keywords instead of colons
error:arg3];

88 Chapter 3. Objective-C -
Google

[myObj short:arg1
longKeyword:arg2
evenLongerKeyword:arg3];

3.2.5 @public @private

Tip: @public @private

C++ public, private protected

@interface MyClass : NSObject {


@public
...
@private
...
}
@end

3.2.6

Tip: @ @ {} @catch

Objective-C

@try {
foo();
}
@catch (NSException *ex) {
bar(ex);
}
@finally {
baz();
}

3.2.7

3.2. 89
Google

Tip:

@interface MyProtocoledClass : NSObject<NSWindowDelegate> {


@private
id<MyFancyDelegate> delegate_;
}
- (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
@end

3.2.8

Tip: block target/selector


4

• 4

• 20

• ^{ ^( ) {

// The entire block fits on one line.


[operation setCompletionBlock:^{ [self onOperationDone]; }];

// The block can be put on a new line, indented four spaces, with the
// closing brace aligned with the first character of the line on which
// block was declared.
[operation setCompletionBlock:^{
[self.delegate newDataAvailable];
}];

// Using a block with a C API follows the same alignment and spacing
// rules as with Objective-C.
dispatch_async(fileIOQueue_, ^{
NSString* path = [self sessionFilePath];
if (path) {
(continues on next page)

90 Chapter 3. Objective-C -
Google

(continued from previous page)

// ...
}
});

// An example where the parameter wraps and the block declaration fits
// on the same line. Note the spacing of |^(SessionWindow *window) {|
// compared to |^{| above.
[[SessionService sharedService]
loadWindowWithCompletionBlock:^(SessionWindow *window) {
if (window) {
[self windowDidLoad:window];
} else {
[self errorLoadingWindow];
}
}];

// An example where the parameter wraps and the block declaration does
// not fit on the same line as the name.
[[SessionService sharedService]
loadWindowWithCompletionBlock:
^(SessionWindow *window) {
if (window) {
[self windowDidLoad:window];
} else {
[self errorLoadingWindow];
}
}];

// Large blocks can be declared out-of-line.


void (^largeBlock)(void) = ^{
// ...
};
[operationQueue_ addOperationWithBlock:largeBlock];

3.3

Objective-C

Objective-C Objective-C naming rules


C++ Google C++
( ) Objective-C

3.3. 91
Google

URL TIFF EXIF

Objective-C++ C++ API


Objective-C Cocoa C++ Cocoa

/ @implementation
Objective-C C++ C++

3.3.1

Tip: –

.h C/C++/Objective-C
.m Objective-C
.mm Objective-C++
.cc C++
.c C

GTMNSString+Utils.h ‘‘GTMNS-
TextView+Autocomplete.h‘‘

3.3.2 Objective-C++

Tip: Objective-C++ /

Cocoa/Objective-C C++ /
@implementation Objective-C C++
C++

// file: cross_platform_header.h

class CrossPlatformAPI {
public:
...
int DoSomethingPlatformSpecific(); // impl on each platform
private:
int an_instance_var_;
};
(continues on next page)

92 Chapter 3. Objective-C -
Google

(continued from previous page)

// file: mac_implementation.mm
#include "cross_platform_header.h"

// A typical Objective-C class, using Objective-C naming.


@interface MyDelegate : NSObject {
@private
int instanceVar_;
CrossPlatformAPI* backEndObject_;
}
- (void)respondToSomething:(id)something;
@end
@implementation MyDelegate
- (void)respondToSomething:(id)something {
// bridge from Cocoa through our C++ backend
instanceVar_ = backEndObject->DoSomethingPlatformSpecific();
NSString* tempString = [NSString stringWithInt:instanceVar_];
NSLog(@"%@", tempString);
}
@end

// The platform-specific implementation of the C++ class, using


// C++ naming.
int CrossPlatformAPI::DoSomethingPlatformSpecific() {
NSString* temp_string = [NSString stringWithInt:an_instance_var_];
NSLog(@"%@", temp_string);
return [temp_string intValue];
}

3.3.3

Tip:

GTMSendMessage

3.3.4

3.3. 93
Google

Tip:

NSString
GTMNSString+Parsing.h GTMStringParsingAdditions

gtm_myCategoryMethodOnAString: Objective-C

3.3.5 Objective-C

Tip:

convertPoint:fromRect: replaceCharactersInRange:withString: Apple s Guide


to Naming Methods

get

- (id)getDelegate; // AVOID
- (id)delegate; // GOOD

Objective-C C++ C++

3.3.6

Tip:
myLocalVariable myInstanceVariable_ Objective-C 2.0 @property
KVO/KVC

int

int w;
int nerr;
(continues on next page)

94 Chapter 3. Objective-C -
Google

(continued from previous page)

int nCompConns;
tix = [[NSMutableArray alloc] init];
obj = [someObject object];
p = [network port];

int numErrors;
int numCompletedConnections;
tickets = [[NSMutableArray alloc] init];
userInfo = [someObject object];
port = [network port];

usernameTextField_
Objective-C 2.0 KVO/KVC
KVO=Key Value Observing KVC=Key Value Coding
/ Objective-C 2.0 @property
@synthesize

k
kInvalidHandle kWritePerm

3.4

C++

3.4.1

Tip: /

3.4. 95
Google

• Copyright 2008 Google Inc.

• Apache 2.0, BSD, LGPL,


GPL

3.4.2

Tip:

// A delegate for NSApplication to handle notifications about app


// launch and shutdown. Owned by the main app controller.
@interface MyAppDelegate : NSObject {
...
}
@end

3.4.3

Tip: |

count

// Sometimes we need |count| to be less than zero.

96 Chapter 3. Objective-C -
Google

// Remember to call |StringWithoutSpaces("foo bar baz")|

3.4.4

Tip: Objective-C

NSObject retained
weak __weak retained
@property Mac IBOutlets
retained

CoreFoundation C++ Objective-C retained


__strong __weak CoreFoundation Objective-C
__weak
clang C++

Objective-C C++

@interface MyDelegate : NSObject {


@private
IBOutlet NSButton *okButton_; // normal NSControl; implicitly weak on Mac only

AnObjcObject* doohickey_; // my doohickey


__weak MyObjcParent *parent_; // so we can send msgs back (owns me)

// non-NSObject pointers...
__strong CWackyCPPClass *wacky_; // some cross-platform object
__strong CFDictionaryRef *dict_;
}
@property(strong, nonatomic) NSString *doohickey;
@property(weak, nonatomic) NSString *parent;
@end

- retained - retained

3.5 Cocoa Objective-C

3.5.1 @private

3.5. Cocoa Objective-C 97


Google

Tip: @private

@interface MyClass : NSObject {


@private
id myInstanceVariable_;
}
// public accessors, setter takes ownership
- (id)myInstanceVariable;
- (void)setMyInstanceVariable:(id)theVar;
@end

3.5.2

Tip:

3.5.3

Tip: init

bug

3.5.4 NSObject

Tip: NSObject @implementation

init... copyWithZone: dealloc init...


copyWithZone: dealloc

3.5.5

98 Chapter 3. Objective-C -
Google

Tip: init 0 nil

0 isa NSObject isa


0 nil

3.5.6 +new

Tip: NSObject new alloc init

Objective-C alloc init retain new

3.5.7 API

Tip: kitchen-sink API

C++ Objective-C –
Objective-C
API

// GTMFoo.m
#import "GTMFoo.h"

@interface GTMFoo (PrivateDelegateHandling)


- (NSString *)doSomethingWithDelegate; // Declare private method
@end

@implementation GTMFoo(PrivateDelegateHandling)
...
- (NSString *)doSomethingWithDelegate {
// Implement this method
}
...
@end

Objective-C 2.0 @interface @implementation

3.5. Cocoa Objective-C 99


Google

@implemenation

Objective-C 2.0

@interface GMFoo () { ... }

@implementation

Bug

Objective-C @implementation
middle truncation
NSString

3.5.8 #import and #include

Tip: #import Objective-C/Objective-C++ #include C/C++

#import #include

• Objective-C Objective-C++ #import

• C C++ #include #define

Objective-C #define #import Objective-C


Objective-C #import

Objective-C C C++ C C++ C


C++ #import #include Objective-C #include

Mac C C++
#define Mac #import
#include #include

#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#import "GTMFoo.h"
#include "base/basictypes.h"

3.5.9

Tip: #import

100 Chapter 3. Objective-C -


Google

Cocoa Foundation
#import
#include Objective-C

#import <Foundation/Foundation.h> // good

#import <Foundation/NSArray.h> // avoid


#import <Foundation/NSString.h>
...

3.5.10 autorelease

Tip: autolease
release

release return

// AVOID (unless you have a compelling performance reason)


MyController* controller = [[MyController alloc] init];
// ... code here that might return ...
[controller release];

// BETTER
MyController* controller = [[[MyController alloc] init] autorelease];

3.5.11 autorelease retain

Tip: autorelease`` ``retain

autorelease retain
autorelease

- (void)setFoo:(GMFoo *)aFoo {
[foo_ autorelease]; // Won't dealloc if |foo_| == |aFoo|
foo_ = [aFoo retain];
}

3.5.12 init dealloc

3.5. Cocoa Objective-C 101


Google

Tip: init dealloc

init dealloc
ivals

- (id)init {
self = [super init];
if (self) {
bar_ = [[NSMutableString alloc] init]; // good
}
return self;
}

- (void)dealloc {
[bar_ release]; // good
[super dealloc];
}

- (id)init {
self = [super init];
if (self) {
self.bar = [NSMutableString string]; // avoid
}
return self;
}

- (void)dealloc {
self.bar = nil; // avoid
[super dealloc];
}

3.5.13

Tip: dealloc @interface

dealloc retained

102 Chapter 3. Objective-C -


Google

dealloc retained @interface


dealloc

3.5.14 setter NSStrings

Tip: NSString setter copy

retain
NSString NSMutableString

- (void)setFoo:(NSString *)aFoo {
[foo_ autorelease];
foo_ = [aFoo copy];
}

3.5.15

Tip: @throw Objective-C OS

-fobjc-exceptions @synchronized
@throw @try @catch @finally

NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN


Mac OS X 10.2

Objective-C Objective-C++

class exceptiontest {
public:
exceptiontest() { NSLog(@"Created"); }
~exceptiontest() { NSLog(@"Destroyed"); }
};

void foo() {
exceptiontest a;
NSException *exception = [NSException exceptionWithName:@"foo"
reason:@"bar"
userInfo:nil];
@throw exception;
}

(continues on next page)

3.5. Cocoa Objective-C 103


Google

(continued from previous page)

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


GMAutoreleasePool pool;
@try {
foo();
}
@catch(NSException *ex) {
NSLog(@"exception raised");
}
return 0;
}

smartptr shared_ptr linked_ptr


STL Objective-C++
C++ Objective-C @try @catch @finally
C++

3.5.16 nil

Tip: nil

nil Objective-C nil

OS X Apple s documentation

C/C++ ��NULL‘‘ C/C++


C/C++

3.5.17 BOOL

Tip: BOOL BOOL YES

Objective-C BOOL BOOL YES``(1) ``NO``(0)


``BOOL BOOL
NO BOOL
YES NO 256 256 512

BOOL _Bool bool C++ Std 4.7.4, 4.12 C99 Std 6.3.1.2
BOOL Boolean Boolean
Objective-C BOOL

104 Chapter 3. Objective-C -


Google

BOOL && || ! BOOL

- (BOOL)isBold {
return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}

- (BOOL)isBold {
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] && [self isBold];
}

YES/NO BOOL

BOOL great = [foo isGreat];


if (great == YES)
// ...be great!

BOOL great = [foo isGreat];


if (great)
// ...be great!

3.5.18 Property

Tip: Property Property Objective-C 2.0


iPhone Mac OS X 10.5 (Leopard)
@property

3.5. Cocoa Objective-C 105


Google

@synthesize

@interface MyClass : NSObject {


@private
NSString *name_;
}
@property(copy, nonatomic) NSString *name;
@end

@implementation MyClass
@synthesize name = name_;
@end

@implementation
@interface @implementation

@interface MyClass : NSObject {


@private
NSString *name_;
}
@property(copy, nonatomic) NSString *name;
@end

@implementation MyClass
@synthesize name = name_;
- (id)init {
...
}
@end

copy Attribute

copy attribute NSString property

NSString setter copy retain

106 Chapter 3. Objective-C -


Google

property synthesize setter getter


get set property nonatomic

Objective-C 2.0 set get

NSString *oldName = myObject.name;


myObject.name = @"Alice";

NSArray *array = [[NSArray arrayWithObject:@"hello"] retain];

NSUInteger numberOfItems = array.count; // not a property


array.release; // not a property

3.5.19

Tip:

@interface MyClass : NSObject // Does a lot of stuff - (void)fooBarBam; @end

@interface MyClass : NSObject { } // Does a lot of stuff - (void)fooBarBam; @end

3.5.20 synthesize

Tip: iOS synthesize

synthesize @synthesize var = var_; self.var = blah;


var = blah;

synthesize CFType CFType @dynamic CFType


retain retain release

3.5. Cocoa Objective-C 107


Google

getter setter @dynamic

// Header file
@interface Foo : NSObject
// A guy walks into a bar.
@property(nonatomic, copy) NSString *bar;
@end

// Implementation file
@interface Foo ()
@property(nonatomic, retain) NSArray *baz;
@end

@implementation Foo
@synthesize bar = bar_;
@synthesize baz = baz_;
@end

3.6 Cocoa

3.6.1

Tip: retain

1. delegate_

2. delegate setDelegate:

3. delegate_ retain

3.6.2 / / MVC

Tip: API @protocol

108 Chapter 3. Objective-C -


Google

• @protocol API @optional``


Objective-C 1.0 ``@optional

3.6. Cocoa 109


Google

110 Chapter 3. Objective-C -


CHAPTER 4

Python -

4.1

2.6

Amit Patel
Antoine Picard
Eugene Jhong
Jeremy Hylton
Matt Smart
Mike Shields

guoqiao v2.19
xuxinkun v2.59
captainfffsama v2.6

• Google Style Guide

• Google -

4.2

Python Google python

111
Google

Vim Emacs
yapf

4.3 Python

4.3.1 Lint

Tip: pylintrc pylint

: pylint Python bug . C C++ (


: less dynamic) , bug . Python ,
. .

: , , .

: pylint . , : a) b) c) ,
d) .

: pylint. ,
. :

dict = 'something awful' # Bad Idea... pylint: disable=redefined-builtin

pylint ( empty-docstring ) .google ‘‘g-‘‘ .

pylint --list-msgs pylint . pylint


--help-msg=C6409 , .

pylint: disable-msg , pylint: disable .

del . del ,
Unused , :

def viking_cafe_order(spam, beans, eggs=None):


del beans, eggs # Unused by vikings.
return spam + spam + spam

‘_‘ , unused_,
_. .

4.3.2

112 Chapter 4. Python -


Google

Tip: , ‘typing‘

: .

: . . x.Obj Obj
x .

: . , .

1. import x .

2. from x import y , x ,y .

3. from x import y as z, y y .

4. z import y as z.( np numpy.)

, sound.effects.echo :

from sound.effects import echo


...
echo.EchoFilter(input, output, delay=0.7, atten=4)

. , .
.

typing six.moves .

4.3.3

Tip:

: . .

: , .

: .

yes:

# absl.flags ( ).
import absl.flags
from doctor.who import jodie

FLAGS = absl.flags.FLAGS

4.3. Python 113


Google

# flags ( ).
from absl import flags
from doctor.who import jodie

FLAGS = flags.FLAGS

No: ( jodie.py doctor/who/ )

# .
# sys.path.
import jodie

sys.path
sys.path import jodie jodie
jodie.py

4.3.4

Tip: ,

: .

: . ,
. , N , .

: . .

: :

1. . ValueError ,
. assert API . assert
, . ,
assert, raise , :

Yes:

def connect_to_next_port(self, minimum):


"""Connects to the next available port.

Args:
minimum: A port value greater or equal to 1024.

Returns:
The new minimum port.

Raises:
(continues on next page)

114 Chapter 4. Python -


Google

(continued from previous page)

ConnectionError: If no available port is found.


"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in␣
,→the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError(f'Min. port must be at least 1024, not
,→{minimum}.')
port = self._find_next_open_port(minimum)
if not port:
raise ConnectionError(
f'Could not connect to service on port {minimum} or␣
,→higher.')
assert port >= minimum, (
f'Unexpected port {port} when minimum was {minimum}.')
return port

No:

def connect_to_next_port(self, minimum):


"""Connects to the next available port.

Args:
minimum: A port value greater or equal to 1024.

Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port(minimum)
assert port is not None
return port

2. , Exception .
Error.

3. except: , Exception StandardError


, , (
). , Python , except: Python
. except: bug.

4. try/except . try , .
, try/except .

5. finally try .

4.3. Python 115


Google

, .

4.3.5

Tip:

: .

: .

: , .

: . , MAX_HOLY_HANDGRENADE_COUNT = 3.
, _ . ,
, _ . . ‘
<>‘_

4.3.6 / /

Tip: .

: , . .
. ( : , ,
nonlocal)

: . .

: (pickled). .
.

: . ,
. , ,
_ , .

4.3.7 &

Tip:

: , & ,
map(), filter(), lambda.( : , ()
)

: . ,
.

116 Chapter 4. Python -


Google

: .

: . : , for , . for
. .

Yes:

result = [mapping_expr for value in iterable if filter_expr]

result = [{'key': value} for value in iterable


if a_long_filter_expression(value)]

result = [complicated_transform(x)
for x in iterable if predicate(x)]

descriptive_name = [
transform({'key': key, 'value': value}, color='black')
for key, value in generate_iterable(some_input)
if complicated_condition_is_met(key, value)
]

result = []
for x in range(10):
for y in range(5):
if x * y > 10:
result.append((x, y))

return {x: complicated_transform(x)


for x in long_generator_function(parameter)
if x is not None}

squares_generator = (x**2 for x in range(10))

unique_names = {user.name for user in users if user is not None}

eat(jelly_bean for jelly_bean in jelly_beans


if jelly_bean.color == 'black')

No:

result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]

return ((x, y, z)
for x in xrange(5)
for y in xrange(5)
if x != y
(continues on next page)

4.3. Python 117


Google

(continued from previous page)

for z in xrange(5)
if y != z)

4.3.8

Tip: , . , .

: , , (in not in)

: , , .
. .

: ( , has_key() ). .

: , , , .
. , . .
, dict.iter*() python2 .

Yes:

for key in adict: ...


if key not in adict: ...
if obj in alist: ...
for line in afile: ...
for k, v in dict.iteritems(): ...

No:

for key in adict.keys(): ...


if not adict.has_key(key): ...
for line in afile.readlines(): ...

4.3.9

Tip: .

: , (yield) , ,
. , , .

: , , . ,
.

: .

118 Chapter 4. Python -


Google

: . Yields: Returns: .

( : )

4.3.10 Lambda

Tip:

: , lambda . map() filter()


.

: .

: . . lambda
, .

: . 60-80 , ( ) .

operator lambda . ,
operator.mul , lambda x, y: x * y .

4.3.11

Tip:

: ( ) if . : x = 1 if cond
else 2 .

: if .

: if . .

: . ,if ,else .
if .

one_line = 'yes' if predicate(value) else 'no'


slightly_split = ('yes' if predicate(value)
else 'no, nein, nyet')
the_longest_ternary_style_that_can_be_done = (
'yes, true, affirmative, confirmed, correct'
if predicate(value)
else 'no, false, negative, nay')

bad_line_breaking = ('yes' if predicate(value) else


'no')
portion_too_long = ('yes'
(continues on next page)

4.3. Python 119


Google

(continued from previous page)

if some_long_module.some_long_predicate_function(
really_long_variable_name)
else 'no, false, negative, nay')

4.3.12

Tip: .

: , , def foo(a, b = 0): . foo


, b 0. , b .

: , ( ) .
, . , Python
, .

: . , .
( ), .

: , :

Yes: def foo(a, b=None):


if b is None:
b = []
Yes: def foo(a, b: Optional[Sequence] = None):
if b is None:
b = []
Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable

No: def foo(a, b=[]):


...
No: def foo(a, b=time.time()): # The time the module was loaded???
...
No: def foo(a, b=FLAGS.my_thing): # sys.argv has not yet been parsed...
...
No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code
...

4.3.13 (properties)

( : fluent python. property , attribute . python


(arrtibute) ,

120 Chapter 4. Python -


Google

(property) .)

Tip: , , . (properties)
.

: . , (attribute) .

: (attribute) get set , .


. Pythonic . , ,
. (properties) .
.

: (properties) get set , : set


get (properties) ( @property ). object
. . . ( :
, @property )

: , .
. @property .

, .
, ( ).

Yes:
import math

class Square:
"""A square with two properties: a writable area and a read-only␣
,→perimeter.

To use:
>>> sq = Square(3)
>>> sq.area
9
>>> sq.perimeter
12
>>> sq.area = 16
>>> sq.side
4
>>> sq.perimeter
16
"""

def __init__(self, side):


self.side = side

(continues on next page)

4.3. Python 121


Google

(continued from previous page)

@property
def area(self):
"""Area of the square."""
return self._get_area()

@area.setter
def area(self, area):
return self._set_area(area)

def _get_area(self):
"""Indirect accessor to calculate the 'area' property."""
return self.side ** 2

def _set_area(self, area):


"""Indirect setter to set the 'area' property."""
self.side = math.sqrt(area)

@property
def perimeter(self):
return self.side * 4

( : , , ?)

4.3.14 True/False

Tip: false

: Python false. ,
false. 0 None, [], {}, false.

: Python . , .

: C/C++ , .

: false, : if foo: if foo != []: .


:

1. None , is is not. None


( : is id(), ,
CPython , id)

2. == false . if not x: . false


None, if not x and x is not None: .

3. ( , , ), false. if not seq: if seq:


if len(seq): if not len(seq): .

122 Chapter 4. Python -


Google

4. , false ( None 0 ).
( len() ) 0 .

Yes:

if not users:
print('no users')

if foo == 0:
self.handle_zero()

if i % 10 == 0:
self.handle_multiple_of_ten()

def f(x=None):
if x is None:
x = []

No:

if len(users) == 0:
print 'no users'

if foo is not None and not foo:


self.handle_zero()

if not i % 10:
self.handle_multiple_of_ten()

def f(x=None):
x = x or []

5. 0 ( ) true.

4.3.15

Tip: . apply(). , for


filter(), map() reduce().

: Python .

: Python , .

Yes: words = foo.split(':')

(continues on next page)

4.3. Python 123


Google

(continued from previous page)

[x[1] for x in my_list if x[2] == 5]

map(math.sqrt, data) # Ok. No inlined lambda expression.

fn(*args, **kwargs)

No: words = string.split(foo, ':')

map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))

apply(fn, args, kwargs)

4.3.16 (Lexical Scoping)

Tip:

: Python , .
, . Python
, . global ,
.

def get_adder(summand1):
"""Returns a function that adds numbers to a given number."""
def adder(summand2):
return summand1 + summand2

return adder

( : , : sum = get_adder(summand1)(summand2)
)

: , . Lisp Scheme( Haskell, ML )


.

: bug. PEP-0227 :

i = 4
def foo(x):
def bar():
print i,
# ...
(continues on next page)

124 Chapter 4. Python -


Google

(continued from previous page)

# A bunch of code here


# ...
for i in x: # Ah, i *is* local to Foo, so this is what Bar sees
print i,
bar()

foo([1, 2, 3]) 1 2 3 3, 1 2 3 4.

( : x , for x i. i ,
foo i , bar() . C++
.)

: .

4.3.17

Tip: , , staticmethod``
``classmethod.

: ( @ ). @classmethod @staticmethod,
. , . ,
my_decorator , :

class C(object):
@my_decorator
def method(self):
# method body ...

class C(object):
def method(self):
# method body ...
method = my_decorator(method)

: . , (enforce invari-
ants), .

: , . ,
. .

: , . .
python . .

( , socket, ),
( pydoc ).
.

4.3. Python 125


Google

. Main .

API staticmethod .
.

classmethod .

4.3.18

Tip: .

Python , ( :
__hash__ __eq__ Python ) .
( ).

Queue Queue . , threading


(locking primitives). , threading.Condition
.

4.3.19

Tip:

: Python , , (metaclasses),
, (on-the-fly compilation), , (object reparenting),
(import hacks), , (modification of system internals), .

: , .

: , . .
( ), ,
.

: .

abc.ABCMeta, collection.
namedtuple, dataclasses , ‘‘enum‘‘ .

4.3.20 python: python3 from __future__ imports

Tip: python3, python3 . .

126 Chapter 4. Python -


Google

: python3 python , python2.7 ,


, python3 .

: , python3 .

: .

: from __future__ imports

from __future__ import , ,


:

from __future__ import absolute_import


from __future__ import division
from __future__ import print_function

absolute imports , division behavior, print function . python3


, . ,
, . from __future__ .
. unicode_literals , , python2.7
. b u unicode
.

six,future,past

python2 python3 , six , future , past .


.

4.3.21

Tip: PEP-484 python3 , pytype


. , pyi . , ,
pyi .

: :

def func(a: int) -> List[int]:

PEP-526 :

a: SomeType = some_func()

python :

a = some_func() #type: SomeType

: . ,
.

4.3. Python 127


Google

: . . .

: python . API ,
pytype . python ,
( ) . ,
TODO , .

( : IDE vim )

4.4 Python

4.4.1

Tip: , .

4.4.2

Tip: 80

1.

2. URL,

3. url

1. Pylint . ‘‘# pylint: disable=invalid-name

with .

Python , , . ,
.

Yes: foo_bar(self, width, height, color='black', design=None, x='foo',


emphasis=None, highlight=0)

if (width == 0 and height == 0 and


color == 'red' and emphasis == 'strong'):

, :

x = ('This will build a very long long '


'long long long long long long string')

URL

128 Chapter 4. Python -


Google

Yes: # See details at


# http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_
,→name_extension_full_specification.html

No: # See details at


# http://www.example.com/us/developer/documentation/api/content/\
# v2.0/csv_file_name_extension_full_specification.html

with .
with.

Yes: with very_long_first_expression_function() as spam, \


very_long_second_expression_function() as beans, \
third_thing() as eggs:
place_order(eggs, beans, spam, beans)

No: with VeryLongFirstExpressionFunction() as spam, \


VeryLongSecondExpressionFunction() as beans:
PlaceOrder(eggs, beans, spam, beans)

Yes: with very_long_first_expression_function() as spam:


with very_long_second_expression_function() as beans:
place_order(beans, spam)

; .

80 yapf 80
80 .

4.4.3

Tip:

, .
.

Yes: if foo:
bar()
while x:
x = bar()
if x and y:
bar()
if not x:
(continues on next page)

4.4. Python 129


Google

(continued from previous page)

bar()
# For a 1 item tuple the ()s are more visually obvious than the comma.
onesie = (foo,)
return foo
return spam, beans
return (spam, beans)
for (x, y) in dict.items(): ...

No: if (x):
bar()
if not(x):
bar()
return (foo)

4.4.4

Tip: 4

tab, tab . , (
), 4 ( ):

Yes: # Aligned with opening delimiter


foo = long_function_name(var_one, var_two,
var_three, var_four)

# Aligned with opening delimiter in a dictionary


foo = {
long_dictionary_key: value1 +
value2,
...
}

# 4-space hanging indent; nothing on first line


foo = long_function_name(
var_one, var_two, var_three,
var_four)

# 4-space hanging indent in a dictionary


foo = {
long_dictionary_key:
long_dictionary_value,
(continues on next page)

130 Chapter 4. Python -


Google

(continued from previous page)

...
}

No: # Stuff on first line forbidden


foo = long_function_name(var_one, var_two,
var_three, var_four)

# 2-space hanging indent forbidden


foo = long_function_name(
var_one, var_two, var_three,
var_four)

# No hanging indent in a dictionary


foo = {
long_dictionary_key:
long_dictionary_value,
...
}

4.4.5

Tip: ], ), } .
YAPF .

Yes: golomb3 = [0, 1, 3]


Yes: golomb4 = [
0,
1,
4,
6,
]

No: golomb4 = [
0,
1,
4,
6
]

4.4. Python 131


Google

4.4.6

Tip: ,

, . , , .
, , .

4.4.7

Tip:

Yes: spam(ham[1], {eggs: 2}, [])

No: spam( ham[ 1 ], { eggs: 2 }, [ ] )

, , , ( ).

Yes: if x == 4:
print(x, y)
x, y = y, x

No: if x == 4 :
print(x , y)
x , y = y , x

, .

Yes: spam(1)

no: spam (1)

Yes: dict['key'] = list[index]

No: dict ['key'] = list [index]

, (=), (==, <, >, !=, <>, <=, >=, in, not in, is, is
not), (and, or, not). , .
.

132 Chapter 4. Python -


Google

Yes: x == 1

No: x<1

= , . , =
.

Yes: def complex(real, imag=0.0): return magic(r=real, i=imag)


Yes: def complex(real, imag: float = 0.0): return Magic(r=real, i=imag)

No: def complex(real, imag = 0.0): return magic(r = real, i = imag)


No: def complex(real, imag: float=0.0): return Magic(r = real, i = imag)

, ( :, #, = ):

Yes:
foo = 1000 # comment
long_name = 2 # comment that should not be aligned

dictionary = {
"foo": 1,
"long_name": 2,
}

No:
foo = 1000 # comment
long_name = 2 # comment that should not be aligned

dictionary = {
"foo" : 1,
"long_name": 2,
}

4.4.8 Shebang

Tip: .py #! . PEP-394 , main #!/usr/


bin/python2 #!/usr/bin/python3 .

( : , Shebang ( Hashbang) (#!),


. Shebang , Unix
Shebang , , , Shebang
. , #!/bin/sh /bin/sh .)

4.4. Python 133


Google

#! Python , , .
#! .

4.4.9

Tip: , ,

Python : . , ,
. __doc__ , pydoc .
( pydoc , ).
( PEP-257 ). : ,
( ). .
, .
.

. ( , Apache 2.0, BSD, LGPL,


GPL), . .

"""A one line summary of the module or program, terminated by a period.

Leave one blank line. The rest of this docstring should contain an
overall description of the module or program. Optionally, it may also
contain a brief description of exported classes and functions and/or usage
examples.

Typical usage example:

foo = ClassFoo()
bar = foo.FunctionBar()
"""

, , , .

, :

1.

2.

3.

, . , ,
. , ,

134 Chapter 4. Python -


Google

, . ,
. See base class
. ,
.

.
. . , 2 .

Args: , , .
80 , 2 4 (
). . *foo( )
**bar ( ), *foo **bar.

Returns: ( Yields: ) . None,


.

Raises: .

def fetch_smalltable_rows(table_handle: smalltable.Table,


keys: Sequence[Union[bytes, str]],
require_all_keys: bool = False,
) -> Mapping[bytes, Tuple[str]]:
"""Fetches rows from a Smalltable.

Retrieves rows pertaining to the given keys from the Table instance
represented by table_handle. String keys will be UTF-8 encoded.

Args:
table_handle: An open smalltable.Table instance.
keys: A sequence of strings representing the key of each table
row to fetch. String keys will be UTF-8 encoded.
require_all_keys: Optional; If require_all_keys is True only
rows with values set for all keys will be returned.

Returns:
A dict mapping keys to the corresponding table row data
fetched. Each row is represented as a tuple of strings. For
example:

{b'Serak': ('Rigel VII', 'Preparer'),


b'Zim': ('Irk', 'Invader'),
b'Lrrr': ('Omicron Persei 8', 'Emperor')}

Returned keys are always bytes. If a key from the keys argument is
missing from the dictionary, then that row was not found in the
table (and require_all_keys must have been False).

(continues on next page)

4.4. Python 135


Google

(continued from previous page)

Raises:
IOError: An error occurred accessing the smalltable.
"""

Args: :

def fetch_smalltable_rows(table_handle: smalltable.Table,


keys: Sequence[Union[bytes, str]],
require_all_keys: bool = False,
) -> Mapping[bytes, Tuple[str]]:
"""Fetches rows from a Smalltable.

Retrieves rows pertaining to the given keys from the Table instance
represented by table_handle. String keys will be UTF-8 encoded.

Args:
table_handle:
An open smalltable.Table instance.
keys:
A sequence of strings representing the key of each table row to
fetch. String keys will be UTF-8 encoded.
require_all_keys:
Optional; If require_all_keys is True only rows with values set
for all keys will be returned.

Returns:
A dict mapping keys to the corresponding table row data
fetched. Each row is represented as a tuple of strings. For
example:

{b'Serak': ('Rigel VII', 'Preparer'),


b'Zim': ('Irk', 'Invader'),
b'Lrrr': ('Omicron Persei 8', 'Emperor')}

Returned keys are always bytes. If a key from the keys argument is
missing from the dictionary, then that row was not found in the
table (and require_all_keys must have been False).

Raises:
IOError: An error occurred accessing the smalltable.
"""

. (Attributes),

136 Chapter 4. Python -


Google

(Attributes) . .

class SampleClass(object):
"""Summary of class here.

Longer class information....


Longer class information....

Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""

def __init__(self, likes_spam=False):


"""Inits SampleClass with blah."""
self.likes_spam = likes_spam
self.eggs = 0

def public_method(self):
"""Performs operation blah."""

. ,
. , .
, .

# We use a weighted dictionary search to find out where i is in


# the array. We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.

if i & (i-1) == 0: # True if i is 0 or a power of 2.

, 2 .

, . Python,
.

# BAD COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1

4.4.10 ,

Tip: ,

4.4. Python 137


Google

, . , ,
.

4.4.11

Tip: , object . .( python2


)

Yes: class SampleClass(object):


pass

class OuterClass(object):

class InnerClass(object):
pass

class ChildClass(ParentClass):
"""Explicitly inherits from another class already."""

No: class SampleClass:


pass

class OuterClass:

class InnerClass:
pass

object (properties) , , PEP-3000


. , ,
__new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__,
and __str__ .

4.4.12

Tip: , % . ,
+ % .

138 Chapter 4. Python -


Google

Yes: x = a + b
x = '%s, %s!' % (imperative, expletive)
x = '{}, {}!'.format(imperative, expletive)
x = 'name: %s; score: %d' % (name, n)
x = 'name: {}; score: {}'.format(name, n)

No: x = '%s%s' % (a, b) # use + in this case


x = '{}{}'.format(a, b) # use + in this case
x = imperative + ', ' + expletive + '!'
x = 'name: ' + name + '; score: ' + str(n)

+ += . ,
, . , ,
.join . ( cStringIO.StringIO .)

Yes: items = ['<table>']


for last_name, first_name in employee_list:
items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name))
items.append('</table>')
employee_table = ''.join(items)

No: employee_table = '<table>'


for last_name, first_name in employee_list:
employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name)
employee_table += '</table>'

, . ,
. , .

Yes:
Python('Why are you hiding your eyes?')
Gollum("I'm scared of lint errors.")
Narrator('"Good!" thought a happy Python reviewer.')

No:
Python("Why are you hiding your eyes?")
Gollum('The lint. It burns. It burns us.')
Gollum("Always the great lint. Watching. Watching.")

. ,
. .
.
, textwrap.dedent() .

4.4. Python 139


Google

No:
long_string = """This is pretty ugly.
Don't do this.
"""

Yes:
long_string = """This is fine if your use case can accept
extraneous leading spaces."""

Yes:
long_string = ("And this is fine if you cannot accept\n" +
"extraneous leading spaces.")

Yes:
long_string = ("And this too is fine if you cannot accept\n"
"extraneous leading spaces.")

Yes:
import textwrap

long_string = textwrap.dedent("""\
This is also fine, because textwrap.dedent()
will collapse common leading spaces in each line.""")

4.4.13 sockets

Tip: sockets , .

, sockets , , :

1. , . ,
.

2. .

3. sockets,
. , ,
.

, , sockets ,
, . :

1. . Python
, . .

140 Chapter 4. Python -


Google

2. , ( ,
).

with :

with open("hello.txt") as hello_file:


for line in hello_file:
print line

with , contextlib.closing():

import contextlib

with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:


for line in front_page:
print line

Legacy AppEngine Python 2.5 with , from __future__ import


with_statement .

4.4.14 TODO

Tip: TODO , . , .

TODO TODO , , email


. . , .
TODO , ( ). TODO
. TODO, .

# TODO([email protected]): Use a "*" here for string repetition.


# TODO(Zeke) Change this to use relations.

TODO , ( 2009 11
) ( XML ).

4.4.15

Tip: , typing

Yes: import os
import sys
from typing import Mapping, Sequence

4.4. Python 141


Google

No: import os, sys

, , .
:

1. __future__

from __future__ import absolute_import


from __future__ import division
from __future__ import print_function

1.

import sys

1.

import tensorflow as tf

1.

from otherproject.ai import mind

, , .

import collections
import queue
import sys

from absl import app


from absl import flags
import bs4
import cryptography
import tensorflow as tf

from book.genres import scifi


from myproject.backend import huxley
from myproject.backend.hgwells import time_machine
from myproject.backend.state_machine import main_loop
from otherproject.ai import body
from otherproject.ai import mind
from otherproject.ai import soul

# Older style code may have these imports down here instead:
#from myproject.backend.hgwells import time_machine
#from myproject.backend.state_machine import main_loop

142 Chapter 4. Python -


Google

4.4.16

Tip:

, , . if ,
else . , try/except , try except .

Yes:

if foo: bar(foo)

No:

if foo: bar(foo)
else: baz(foo)

try: bar(foo)
except ValueError: baz(foo)

try:
bar(foo)
except ValueError: baz(foo)

4.4.17

Tip: Python , , ,
. , (property) .

( : , :
! , . Pythonic )

, , , get_foo() set_foo()
. (property) ,
. , , .

4.4.18

Tip: : module_name ; : package_name ; : ClassName ; : method_name


; : ExceptionName ; : function_name ; : GLOBAL_CONSTANT_NAME ;
: global_var_name ; : instance_var_name ; : function_parameter_name ;
: local_var_name . , , ,

4.4. Python 143


Google

, . .py
, .

1. , , try/except e, with
f.

2. / (-)

3. (Python , __init__)

1. (Internal) , , .

2. (_) protected ( from module import *


).

3. (__) .

4. . Java, .

5. ( CapWords, Pascal ),
( lower_with_under.py). CapWords.py
, , , .

python .py -.
, exec "$0.py" "$@" bash .

Python Guido

Type Public Internal


Modules lower_with_under _lower_with_under
Packages lower_with_under
Classes CapWords _CapWords
Exceptions CapWords
Functions lower_with_under() _lower_with_under()
Global/Class Con- CAPS_WITH_UNDER
_CAPS_WITH_UNDER
stants
Global/Class Vari- lower_with_under _lower_with_under
ables
Instance Variables lower_with_under _lower_with_under (protected) or
__lower_with_under (private)
Method Names lower_with_under() _lower_with_under() (protected) or
__lower_with_under() (private)
Function/Method Pa- lower_with_under
rameters
Local Variables lower_with_under

144 Chapter 4. Python -


Google

4.4.19 Main

Tip: , .
(main functionality) , . main() .

Python , pydoc . if
__name__ == '__main__' , .

absl, app.run :

from absl import app


...

def main(argv):
# process non-flag arguments
...

if __name__ == '__main__':
app.run(main)

, :

def main():
...

if __name__ == '__main__':
main()

. , ,
pydoc .

4.4.20

Tip: , ,

. 40 ,
. , ,
bug. , . ,
, .

4.4.21

4.4. Python 145


Google

1. PEP-484 <https://www.python.org/dev/peps/pep-0484/> _

2. self cls

3. Any

4.

1. API

2.

3.

4.

5. .
.

. .

def my_method(self,
first_var: int,
second_var: Foo,
third_var: Optional[Bar]) -> int:
...

. , ,
.

def my_method(self, first_var: int) -> int:


...

, , , 4 .

def my_method(
self, first_var: int) -> Tuple[MyLongType1, MyLongType1]:
...

, , 4 ,
) def

Yes:
def my_method(
self, other_arg: Optional[MyLongType]
) -> Dict[OtherLongType, MyLongType]:
...

pylint ) ( , .

146 Chapter 4. Python -


Google

No:
def my_method(self,
other_arg: Optional[MyLongType]
) -> Dict[OtherLongType, MyLongType]:
...

, . ,
.

def my_method(
self,
first_var: Tuple[List[MyLongType1],
List[MyLongType2]],
second_var: List[Dict[
MyLongType3, MyLongType4]]) -> None:
...

, alias.
‘‘:‘‘ 4 .

Yes:
def my_function(
long_variable_name:
long_module_name.LongTypeName,
) -> None:
...

No:
def my_function(
long_variable_name: long_module_name.
LongTypeName,
) -> None:
...

, ,

class MyClass:

def __init__(self,
stack: List["MyClass"]) -> None:

PEP-008 , = .

4.4. Python 147


Google

Yes:
def func(a: int = 0) -> int:
...

No:
def func(a:int=0) -> int:
...

NoneType

python , NoneType , , None NoneType


. None, . Union,
, Optional. Optional. PEP-484
a: Text = None a: Optional[Text] = None, ,
.

Yes:
def func(a: Optional[Text], b: Optional[Text] = None) -> Text:
...
def multiple_nullable_union(a: Union[None, Text, int]) -> Text
...

No:
def nullable_union(a: Union[None, Text]) -> Text:
...
def implicit_optional(a: Text = None) -> Text:
...

, . ,
‘‘_‘‘ . , :

_ShortName = module_with_long_name.TypeWithLongName
ComplexMap = Mapping[Text, List[Tuple[int, int]]]

# type: ignore . pytype


( lint):

# pytype: disable=attribute-error

, :

148 Chapter 4. Python -


Google

# type::

a = SomeUndecoratedFunction() # type: Foo

, :

a: Foo = SomeUndecoratedFunction()

Tuples vs Lists

Lists . Tuples
, . ( :
, python ,list tuple , ,
list tuple )

a = [1, 2, 3] # type: List[int]


b = (1, 2, 3) # type: Tuple[int, ...]
c = (1, "2", 3.5) # type: Tuple[int, Text, float]

TypeVars

python . TypeVars.

from typing import List, TypeVar


T = TypeVar("T")
...
def next(l: List[T]) -> T:
return l.pop()

TypeVar

AddableType = TypeVar("AddableType", int, float, Text)


def add(a: AddableType, b: AddableType) -> AddableType:
return a + b

typing AnyStr. bytes, unicode


.

from typing import AnyStr


def check_length(x: AnyStr) -> AnyStr:
if len(x) <= 42:
return x
raise ValueError()

python . python3
, str. Text . , .
python2 , Text. , str . unicode,

4.4. Python 149


Google

python3 . , python ,‘‘str‘‘


.

No:
def py2_code(x: str) -> unicode:
...

, bytes.

def deals_with_binary_data(x: bytes) -> bytes:


...

python2 ‘‘str‘‘ ‘‘unicode‘‘, python3 str.

from typing import Text


...
def py2_compatible(x: Text) -> Text:
...
def py3_only(x: str) -> str:
...

, Union ,
.

from typing import Text, Union


...
def py2_compatible(x: Union[bytes, Text]) -> Union[bytes, Text]:
...
def py3_only(x: Union[bytes, str]) -> Union[bytes, str]:
...

, ,
AnyStr. python3

typing , . typing
, :

from typing import Any, Dict, Optional

, typing
, . ,
‘‘import x as y‘‘ :

from typing import Any as AnyType

150 Chapter 4. Python -


Google

, ,
. , .
if TYPE_CHECKING: .

1. string, python3.6
. python3.6 , .

2. , . , ,
.

3. .

4. .

5. , .

import typing
if typing.TYPE_CHECKING:
import sketch
def f(x: "sketch.Sketch"): ...

, .
, , .
Any . alias ,
(Any Any,
). .

from typing import Any

some_mod = Any # some_mod.py imports this module.


...

def my_method(self, var: "some_mod.SomeType") -> None:


...

, . , Any .

def get_names(employee_ids: List[int]) -> Dict[int, Any]:


...

# These are both interpreted as get_names(employee_ids: List[Any]) ->␣


Dict[Any, Any]
,→

def get_names(employee_ids: list) -> Dict:


...

(continues on next page)

4.4. Python 151


Google

(continued from previous page)

def get_names(employee_ids: List) -> Dict:


...

Any , . , TypeVar
.

def get_names(employee_ids: List[Any]) -> Dict[Any, Text]:


"""Returns a mapping from employee ID to employee name for given IDs."""

T = TypeVar('T')
def get_names(employee_ids: List[T]) -> Dict[T, Text]:
"""Returns a mapping from employee ID to employee name for given IDs."""

4.5

, , .
, . , .

, ,
. , .
, . .

Revision 2.60

Amit Patel
Antoine Picard
Eugene Jhong
Gregory P. Smith
Jeremy Hylton
Matt Smart
Mike Shields
Shane Liebling

152 Chapter 4. Python -


CHAPTER 5

Shell -

Contents

• Shell -

5.1

1.26

Paul Armstrong

Bean Zhang v1.26

• Google Style Guide

• Google -

5.2

5.2.1 Shell

153
Google

Tip: Bash shell

#!/bin/bash set shell bash


<script_name>

shell bash shell

Solaris SVR4
Bourne shell

5.2.2 Shell

Tip: Shell

Shell

• shell

• shell

• ${PHPESTATUS} Python

• 100 Python Shell

5.3 Shell

5.3.1

Tip: .sh .sh

shell

.sh

154 Chapter 5. Shell -


Google

5.3.2 SUID / SGID

Tip: SUID(Set User ID) SGID(Set Group ID) shell

shell SUID/SGID shell bash


SUID

sudo

5.4

5.4.1 STDOUT vs STDERR

Tip: STDERR

err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2
}

if ! do_something; then
err "Unable to do_something"
exit "${ E_DID_NOTHING}"
fi

5.5

5.5.1

Tip:

5.4. 155
Google

#!/bin/bash
#
# Perform hot backups of Oracle databases.

5.5.2

Tip:

#!/bin/bash
#
# Perform hot backups of Oracle databases.

export PATH='/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin'

#######################################
# Cleanup files from the backup dir
# Globals:
# BACKUP_DIR
# ORACLE_SID
# Arguments:
# None
# Returns:
# None
#######################################
cleanup() {
...
}

5.5.3

156 Chapter 5. Shell -


Google

Tip:

5.5.4 TODO

Tip: TODO

C++

TODOs TODO TODO


bug ticket

# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)

5.6

5.6.1

Tip:

5.6.2

Tip: 80

80 here document
80

# DO use 'here document's


cat <<END;
I am an exceptionally long
string.
(continues on next page)

5.6. 157
Google

(continued from previous page)

END

# Embedded newlines are ok too


long_string="I am an exceptionally
long string."

5.6.3

Tip:

2 | || &&

# All fits on one line


command1 | command2

# Long commands
command1 \
| command2 \
| command3 \
| command4

5.6.4

Tip: ; do , ; then while , for , if

shell ; do , ; then
if/for/while else

for dir in ${ dirs_to_cleanup}; do


if [[ -d "${ dir}/${ ORACLE_SID}" ]]; then
log_date "Cleaning up old files in ${ dir}/${ ORACLE_SID}"
rm "${ dir}/${ ORACLE_SID}/"*
if [[ "$?" -ne 0 ]]; then
error_message
fi
(continues on next page)

158 Chapter 5. Shell -


Google

(continued from previous page)

else
mkdir -p "${ dir}/${ ORACLE_SID}"
if [[ "$?" -ne 0 ]]; then
error_message
fi
fi
done

5.6.5 case

Tip:

• 2

• ;;

• ;;

case esac
;& ;;&

case "${ expression}" in


a)
variable="..."
some_command "${ variable}" "${ other_expr}" ...
;;
absolute)
actions="relative"
another_command "${ actions}" "${ other_expr}" ...
;;
*)
error "Unexpected expression '${ expression}'"
;;
esac

;;
;;
;;

verbose='false'
aflag=''
bflag=''
files=''
(continues on next page)

5.6. 159
Google

(continued from previous page)

while getopts 'abf:v' flag; do


case "${ flag}" in
a) aflag='true' ;;
b) bflag='true' ;;
f) files="${ OPTARG}" ;;
v) verbose='true' ;;
*) error "Unexpected option ${ flag}" ;;
esac
done

5.6.6

Tip: ${var} $var

1.

2.

3. shell

# Section of recommended cases.

# Preferred style for 'special' variables:


echo "Positional: $1" "$5" "$3"
echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ ..."

# Braces necessary:
echo "many parameters: ${ 10}"

# Braces avoiding confusion:


# Output is "a0b0c0"
set -- a b c
echo "${ 1}0${ 2}0${ 3}0"

# Preferred style for other variables:


echo "PATH=${ PATH}, PWD=${ PWD}, mine=${ some_var}"
while read f; do
echo "file=${ f}"
(continues on next page)

160 Chapter 5. Shell -


Google

(continued from previous page)

done < <(ls -l /tmp)

# Section of discouraged cases

# Unquoted vars, unbraced vars, brace-quoted single letter


# shell specials.
echo a=$avar "b=$bvar" "PID=${ $}" "${ 1}"

# Confusing use: this is expanded as "${1}0${2}0${3}0",


# not "${10}${20}${30}
set -- a b c
echo "$10$20$30"

5.6.7

Tip:

• shell

• [[

• $@ $*

# 'Single' quotes indicate that no substitution is desired.


# "Double" quotes indicate that substitution is required/tolerated.

# Simple examples
# "quote command substitutions"
flag="$(some_command and its args "$@" 'quoted separately')"

# "quote variables"
echo "${ flag}"

# "never quote literal integers"


value=32
# "quote command substitutions", even when you expect integers
number="$(generate_number)"

# "prefer quoting words", not compulsory


readonly USE_INTEGER='true'
(continues on next page)

5.6. 161
Google

(continued from previous page)

# "quote shell meta characters"


echo 'Hello stranger, and well met. Earn lots of $$$'
echo "Process $$: Done making \$\$\$."

# "command options or path names"


# ($1 is assumed to contain a value here)
grep -li Hugo /dev/null "$1"

# Less simple examples


# "quote variables, unless proven false": ccs might be empty
git send-email --to "${ reviewers}" ${ ccs:+"--cc" "${ ccs}"}

# Positional parameter precautions: $1 might be unset


# Single quotes leave regex as-is.
grep -cP '([Ss]pecial|\|?characters*)$' ${ 1:+"$1"}

# For passing on arguments,


# "$@" is right almost everytime, and
# $* is wrong almost everytime:
#
# * $* and $@ will split on spaces, clobbering up arguments
# that contain spaces and dropping empty strings;
# * "$@" will retain arguments as-is, so no args
# provided will result in no args being passed on;
# This is in most cases what you want to use for passing
# on arguments.
# * "$*" expands to one argument, with all args joined
# by (usually) spaces,
# so no args provided will result in one empty string
# being passed on.
# (Consult 'man bash' for the nit-grits ;-)

set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$*"; echo "$#, $@")
set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$@"; echo "$#, $@")

5.7

5.7.1

162 Chapter 5. Shell -


Google

Tip: $(command)

$(command)

# This is preferred:
var="$(command "$(command1)")"

# This is not:
var="`command \`command1\``"

5.7.2 test [ [[

Tip: [[ ... ]] [ , test , /usr/bin/[

[[ ]] [[ ... ]]
[[ ... ]] [ ... ]

# This ensures the string on the left is made up of characters in the


# alnum character class followed by the string name.
# Note that the RHS should not be quoted here.
# For the gory details, see
# E14 at http://tiswww.case.edu/php/chet/bash/FAQ
if [[ "filename" =~ ^[[:alnum:]]+name ]]; then
echo "Match"
fi

# This matches the exact pattern "f*" (Does not match in this case)
if [[ "filename" == "f*" ]]; then
echo "Match"
fi

# This gives a "too many arguments" error as f* is expanded to the


# contents of the current directory
if [ "filename" == f* ]; then
echo "Match"
fi

5.7.3

5.7. 163
Google

Tip:

Bash

# Do this:
if [[ "${ my_var}" = "some_string" ]]; then
do_something
fi

# -z (string length is zero) and -n (string length is not zero) are


# preferred over testing for an empty string
if [[ -z "${ my_var}" ]]; then
do_something
fi

# This is OK (ensure quotes on the empty side), but not preferred:


if [[ "${ my_var}" = "" ]]; then
do_something
fi

# Not this:
if [[ "${ my_var}X" = "some_stringX" ]]; then
do_something
fi

‘-z‘ ‘-n‘

# Use this
if [[ -n "${ my_var}" ]]; then
do_something
fi

# Instead of this as errors can occur if ${my_var} expands to a test


# flag
if [[ "${ my_var}" ]]; then
do_something
fi

5.7.4

164 Chapter 5. Shell -


Google

Tip:

- ./* *

# Here's the contents of the directory:


# -f -r somedir somefile

# This deletes almost everything in the directory by force


psa@bilby$ rm -v *
removed directory: `somedir'
removed `somefile'

# As opposed to:
psa@bilby$ rm -v ./*
removed `./-f'
removed `./-r'
rm: cannot remove `./somedir': Is a directory
removed `./somefile'

5.7.5 Eval

Tip: eval

Eval

# What does this set?


# Did it succeed? In part or whole?
eval $(set_my_variables)

# What happens if one of the returned values has a space in it?


variable="$(eval some_function)"

5.7.6 while

Tip: for while while


shell shell

while shell bug

5.7. 165
Google

last_line='NULL'
your_command | while read line; do
last_line="${ line}"
done

# This will output 'NULL'


echo "${ last_line}"

for

total=0
# Only do this if there are no spaces in return values.
for value in $(command); do
total+="${ value}"
done

shell bash while


shell

total=0
last_file=
while read count filename; do
total+="${ count}"
last_file="${ filename}"
done < <(your_command | uniq -c)

# This will output the second field of the last line of output from
# the command.
echo "Total = ${ total}"
echo "Last one = ${ last_file}"

shell while
awk shell

# Trivial implementation of awk expression:


# awk '$3 == "nfs" { print $2 " maps to " $1 }' /proc/mounts
cat /proc/mounts | while read src dest type opts rest; do
if [[ ${ type} == "nfs" ]]; then
echo "NFS ${ dest} maps to ${ src}"
fi
done

166 Chapter 5. Shell -


Google

5.8

5.8.1

Tip: ::
function

:: Google

# Single function
my_func() {
...
}

# Part of a package
mypackage::my_func() {
...
}

() function

5.8.2

Tip:

for zone in ${ zones}; do


something_with "${ zone}"
done

5.8.3

Tip:

5.8. 167
Google

# Constant
readonly PATH_TO_FILES='/some/path'

# Both constant and environment


declare -xr ORACLE_SID='PROD'

getopts getopts
declare
readonly export

VERBOSE='false'
while getopts 'v' flag; do
case "${ flag}" in
v) VERBOSE='true' ;;
esac
done
readonly VERBOSE

5.8.4

Tip:

Google maketemplate make_template


make-template

5.8.5

Tip: readonly declare -r

shell

zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"


if [[ -z "${ zip_version}" ]]; then
error_message
else
readonly zip_version
fi

5.8.6

168 Chapter 5. Shell -


Google

Tip: local

local

local

my_func2() {
local name="$1"

# Separate lines for declaration and assignment:


local my_var
my_var="$(my_func)" || return

# DO NOT do this: $? contains the exit code of 'local', not my_func


local my_var="$(my_func)"
[[ $? -eq 0 ]] || return

...
}

5.8.7

Tip:

includes set

5.8.8 main

Tip: main

main

main

main "$@"

main

5.8. 169
Google

5.9

5.9.1

Tip:

$? if

if ! mv "${ file_list}" "${ dest_dir}/" ; then


echo "Unable to move ${ file_list} to ${ dest_dir}" >&2
exit "${ E_BAD_MOVE}"
fi

# Or
mv "${ file_list}" "${ dest_dir}/"
if [[ "$?" -ne 0 ]]; then
echo "Unable to move ${ file_list} to ${ dest_dir}" >&2
exit "${ E_BAD_MOVE}"
fi

Bash PIPESTATUS

tar -cf - ./* | ( cd "${ dir}" && tar -xf - )


if [[ "${ PIPESTATUS[0]}" -ne 0 || "${ PIPESTATUS[1]}" -ne 0 ]]; then
echo "Unable to tar files to ${ dir}" >&2
fi

PIPESTATUS
PIPESTATUS [ PIPESTATUS

tar -cf - ./* | ( cd "${ DIR}" && tar -xf - )


return_codes=(${ PIPESTATUS[*]})
if [[ "${ return_codes[0]}" -ne 0 ]]; then
do_something
fi
if [[ "${ return_codes[1]}" -ne 0 ]]; then
do_something_else
fi

170 Chapter 5. Shell -


Google

5.9.2

Tip: shell

bash(1) sed

# Prefer this:
addition=$((${ X} + ${ Y}))
substitution="${ string/#foo/bar}"

# Instead of this:
addition="$(expr ${ X} + ${ Y})"
substitution="$(echo "${ string}" | sed -e 's/^foo/bar/')"

5.10

C++

5.10. 171
Google

172 Chapter 5. Shell -


CHAPTER 6

Javascript -

6.1

Google JavaScript JavaScript

6.2 Javascript

6.2.1 var

var

var
var document
window var

6.2.2

• NAMES_LIKE_THIS

• @const

• IE const

173
Google

CONSTANT_VALUE_CASE

number string boolean

@const const
const IE const

@const

@const CONSTANT_VALUE_CASE

/**
*
* @type {number}
*/
goog.example.TIMEOUT_IN_MILLISECONDS = 60;

1 60
@const

/**
* Map of URL to response string.
* @const
*/
MyClass.fetchedUrlCache_ = new goog.structs.Map();

6.2.3

174 Chapter 6. Javascript -


Google

// 1.
MyClass.prototype.myMethod = function() {
return 42;
} // .

(function() {
//
})();

var x = {
'i': 1,
'j': 2
} // .

// 2. IE firefox .
// .
[normalVersion, ffVersion][isIE]();

var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] //

// 3.
-1 == resultOfOperation() || die();

1. js 42
42

2. no sush property in undefined


x[normalVersion, ffVersion][isIE]()

3. die resultOfOperation() NaN THINGS_TO_EAT


die()

js
) } ]
( { [ js

6.2. Javascript 175


Google

var foo = function() {


return true;
}; //

function foo() {
return true;
} //

6.2.4

6.2.5

if (x) {
function foo() {}
}

ECMAScript ECMA-262 13
14 EcmaScript ECMAScript
,

if (x) {
var foo = function() {}
}

6.2.6

6.2.7

176 Chapter 6. Javascript -


Google

hack

6.2.8

string.charAt(3)
string[3] DOM

6.2.9

var x = new Boolean(false);


if (x) {
alert('hi'); // hi
}

var x = Boolean(0);
if (x) {
alert('hi'); //
}
typeof Boolean(0) == 'boolean';
typeof new Boolean(0) == 'object';

6.2.10

Javascript class B
class D

Closure goog.inherits()

function D() {
goog.base(this)
}
goog.inherits( D, B );

(continues on next page)

6.2. Javascript 177


Google

(continued from previous page)

D.prototype.method =function() {
...
};

6.2.11

/** */ function SomeConstructor() { this.someProperty = 1; } Foo.prototype.


someMethod = function() { ... };

new

Foo.prototype.bar = function() {
/* ... */
};

/** @constructor */
function Foo() {
this.bar = value;
}

JavaScript

6.2.12

this.foo = null

o.prototype.dispose = function() {
this.property_ = null;
};

Foo.prototype.dispose = function() {
delete his.property_;
};

JavaScript
if (key in obj)

178 Chapter 6. Javascript -


Google

6.2.13

JS

DOM

function foo(element, a, b) {
element.onclick = function() { /* a b */ };
}

a b

function foo(element, a, b) {
element.onclick = bar(a, b);
}

function bar(a, b) {
return function() { /* a b */ }
}

6.2.14 eval()

RPC

eval() eval()
eval eval
RPC

users = [
{
name: 'Eric',
id: 37824,
email: '[email protected]'
},
{
name: 'xtof',
id: 31337,
email: '[email protected]'
},
...
];

6.2. Javascript 179


Google

eval() RPC XMLHttpRequest RPC


JavaScript

var userOnline = false;


var user = 'nusrat';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false);
xmlhttp.send('');
//
// userOnline = true;
if (xmlhttp.status == 200) {
eval(xmlhttp.responseText);
}
// userOnline true

6.2.15 with() {}

with with

with (foo) {
var x = 3;
return x;
}

x foo setter
3 with

6.2.16 this

this eval DOM


HTML
call() apply()

this

180 Chapter 6. Javascript -


Google

6.2.17 for-in

for-in 0 length-1

function printArray(arr) {
for (var key in arr) {
print(arr[key]);
}
}

printArray([0,1,2,3]); //

var a = new Array(10);


printArray(a); //

a = document.getElementsByTagName('*');
printArray(a); //

a = [0,1,2,3];
a.buhu = 'wine';
printArray(a); //

a = new Array;
a[3] = 3;
printArray(a); //

function printArray(arr) {
var l = arr.length;
for (var i = 0; i < l; i++) {
print(arr[i]);
}
}

6.2.18

JS Date RegExp String

6.2. Javascript 181


Google

6.2.19

var myString = 'A rather long string of English text, an error message \
actually that just keeps going and going -- an error \
message to make the Energizer bunny blush (right through \
those Schwarzenegger shades)! Where was I? Oh yes, \
you\'ve got an error and all the extraneous whitespace is \
just gravy. Have a nice day.';

ECMAScript

var myString = 'A rather long string of English text, an error message ' +
'actually that just keeps going and going -- an error ' +
'message to make the Energizer bunny blush (right through ' +
'those Schwarzenegger shades)! Where was I? Oh yes, ' +
'you\'ve got an error and all the extraneous whitespace is ' +
'just gravy. Have a nice day.';

6.2.20

// 3
var a1 = new Array(x1, x2, x3);

// 2
var a2 = new Array(x1, x2);

// If x1 is a number and it is a natural number the length will be x1.


// If x1 is a number but not a natural number this will throw an exception.
// Otherwise the array will have one element with x1 as its value.
var a3 = new Array(x1);

// 0
var a4 = new Array();

182 Chapter 6. Javascript -


Google

var a = [x1, x2, x3];


var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];

var o = new Object();

var o2 = new Object();


o2.a = 0;
o2.b = 1;
o2.c = 2;
o2['strange key'] = 3;

var o = {};

var o2 = {
a: 0,
b: 1,
c: 2,
'strange key': 3
};

6.2.21

Object.prototype Array.prototype
Function.prototype

6.2.22 Internet Explorer

var f = function () {
/*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/
};

JavaScript

6.2. Javascript 183


Google

6.3 Javascript

6.3.1

functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis


EnumNamesLikeThis methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foo.
namespaceNamesLikeThis.bar filenameslikethis.js

opt_

var_args var_args
arguments

@param

getter setter

EcmaScript 5 getter setter getter

/**
* -- .
*/
var foo = { get next() { return this.nextId++; } };
};

getter setter getFoo()


setFoo(value) isFoo()

184 Chapter 6. Javascript -


Google

JavaScript

JavaScript

Project
Sloth sloth.*

var sloth = {};

sloth.sleep = function() {
...
};

JavaScript the Closure Library Dojo toolkit

goog.provide('sloth');

sloth.sleep = function() {
...
};

sloths hats
Sloth sloth.hats

foo.hats.* foo.hats.*

foo.require('foo.hats');
/**
* --
* @constructor
* @extends {foo.hats.RoundHat}
*/
(continues on next page)

6.3. Javascript 185


Google

(continued from previous page)

foo.hats.BowlerHat = function() {
};

API API
API

foo.provide('googleyhats.BowlerHat');

foo.require('foo.hats');
/**
* @constructor
* @extends {foo.hats.RoundHat}
*/
googleyhats.BowlerHat = function() {
...
};
goog.exportSymbol('foo.hats.BowlerHat', googleyhats.BowlerHat);

/**
* @constructor
*/
some.long.namespace.MyClass = function() {
};

/**
* @param {some.long.namespace.MyClass} a
*/
some.long.namespace.MyClass.staticHelper = function(a) {
...
};

myapp.main = function() {
var MyClass = some.long.namespace.MyClass;
var staticHelper = some.long.namespace.MyClass.staticHelper;
staticHelper(new MyClass());
};

goog.scope

186 Chapter 6. Javascript -


Google

myapp.main = function() {
var namespace = some.long.namespace;
namespace.MyClass.staticHelper(new namespace.MyClass());
};

/** @enum {string} */


some.long.namespace.Fruit = {
APPLE: 'a',
BANANA: 'b'
};

myapp.main = function() {
var Fruit = some.long.namespace.Fruit;
switch (fruit) {
case Fruit.APPLE:
...
case Fruit.BANANA:
...
}
};

myapp.main = function() {
var MyClass = some.long.namespace.MyClass;
MyClass.staticHelper(null);
};

.js
- _ _ -

6.3.2 toString()

toString()

toString()
toString()

6.3. Javascript 187


Google

6.3.3

6.3.4

window
window window

6.3.5

C++

if (something) {
// ...
} else {
//
}

var arr = [1, 2, 3]; // [ ]


var obj = {a: 1, b: 2, c: 3}; // [ ]

//
var inset = {
top: 10,
right: 20,
bottom: 15,
left: 12
};

//
(continues on next page)

188 Chapter 6. Javascript -


Google

(continued from previous page)

this.rows_ = [
'"Slartibartfast" <[email protected]>',
'"Zaphod Beeblebrox" <[email protected]>',
'"Ford Prefect" <[email protected]>',
'"Arthur Dent" <[email protected]>',
'"Marvin the Paranoid Android" <[email protected]>',
'[email protected]'
];

//
goog.dom.createDom(goog.dom.TagName.DIV, {
id: 'foo',
className: 'some-css-class',
style: 'display:none'
}, 'Hello, world!');

CORRECT_Object.prototype = {
a: 0,
b: 1,
lengthyName: 2
};

WRONG_Object.prototype = {
a : 0,
b : 1,
lengthyName: 2
};

80
80

// 80
//
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
(continues on next page)

6.3. Javascript 189


Google

(continued from previous page)

// ...
};

//
//
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
};

// 80
//
function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
}

//
//
function bar(veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
}

if (veryLongFunctionNameA(
veryLongArgumentName) ||
veryLongFunctionNameB(
veryLongArgumentName)) {
veryLongFunctionNameC(veryLongFunctionNameD(
veryLongFunctioNameE(
veryLongFunctionNameF)));
}

190 Chapter 6. Javascript -


Google

function

prefix.something.reallyLongFunctionName('whatever', function(a1, a2) {


if (a1.equals(a2)) {
someOtherLongFunctionName(a1);
} else {
andNowForSomethingCompletelyDifferent(a2.parrot);
}
});

var names = prefix.something.myExcellentMapFunction(


verboselyNamedCollectionOfItems,
function(item) {
return item.name;
});

goog.scope

goog.scope the Closure Library

goog.scope

goog.scope(function() { goog.provide goog.


require scope // goog.
scope

C++ goog.scope 0

goog.scope(function() {
var Button = goog.ui.Button;

Button = function() { ... };


...

goog.provide('my.module');

goog.require('goog.dom');
goog.require('goog.ui.Button');

goog.scope(function() {
(continues on next page)

6.3. Javascript 191


Google

(continued from previous page)

var Button = goog.ui.Button;


var dom = goog.dom;

// Alias new types after the constructor declaration.


my.module.SomeType = function() { ... };
var SomeType = my.module.SomeType;

// Declare methods on the prototype as usual:


SomeType.prototype.findButton = function() {
// Button as aliased above.
this.button = new Button(dom.getElement('my-button'));
};
...
}); // goog.scope

4 2

someWonderfulHtml = '' +
getEvenMoreHtml(someReallyInterestingValues, moreValues,
evenMoreParams, 'a duck', true, 72,
slightlyMoreMonkeys(0xfff)) +
'';

thisIsAVeryLongVariableName =
hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();

thisIsAVeryLongVariableName = 'expressionPartOne' + someMethodThatIsLong() +


thisIsAnEvenLongerOtherFunctionNameThatCannotBeIndentedMore();

someValue = this.foo(
shortArg,
'Some really long string arg - this is a pretty common case, actually.',
shorty2,
this.bar());

if (searchableCollection(allYourStuff).contains(theStuffYouWant) &&
!ambientNotification.isActive() && (client.isAmbientSupported() ||
client.alwaysTryAmbientAnyways())) {
ambientNotification.activate();
}

192 Chapter 6. Javascript -


Google

doSomethingTo(x);
doSomethingElseTo(x);
andThen(x);

nowDoSomethingWith(y);

andNowWith(z);

var x = a ? b : c; // All on one line if it will fit.

// Indentation +4 is OK.
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;

// Indenting to the line position of the first operand is also OK.


var z = a ?
moreComplicatedB :
moreComplicatedC;

var x = foo.bar().
doSomething().
doSomethingElse();

6.3.6

delete typeof void return throw


case in new

6.3.7

' "

6.3. Javascript 193


Google

' " HTML

var msg = 'This is some HTML';

6.3.8

@private @protected JSDoc

JSDoc @private @protected

--jscomp_warning=visibility

@private

@private @private
instanceof

@protected

// 1
// AA_PrivateClass_ AA_init_

/**
* @private
* @constructor
*/
AA_PrivateClass_ = function() {
};

/** @private */
function AA_init_() {
return new AA_PrivateClass_();
}

AA_init_();

@private

@protected

C++ JAVA private protected


C++

// File 1.

(continues on next page)

194 Chapter 6. Javascript -


Google

(continued from previous page)

/** @constructor */
AA_PublicClass = function() {
/** @private */
this.privateProp_ = 2;

/** @protected */
this.protectedProp = 4;
};

/** @private */
AA_PublicClass.staticPrivateProp_ = 1;

/** @protected */
AA_PublicClass.staticProtectedProp = 31;

/** @private */
AA_PublicClass.prototype.privateMethod_ = function() {};

/** @protected */
AA_PublicClass.prototype.protectedMethod = function() {};

// File 2.

/**
* @return {number} The number of ducks we've arranged in a row.
*/
AA_PublicClass.prototype.method = function() {
// Legal accesses of these two properties.
return this.privateProp_ + AA_PublicClass.staticPrivateProp_;
};

// File 3.

/**
* @constructor
* @extends {AA_PublicClass}
*/
AA_SubClass = function() {
// Legal access of a protected static property.
AA_PublicClass.staticProtectedProp = this.method();
};
goog.inherits(AA_SubClass, AA_PublicClass);

(continues on next page)

6.3. Javascript 195


Google

(continued from previous page)

/**
* @return {number} The number of ducks we've arranged in a row.
*/
AA_SubClass.prototype.method = function() {
// Legal access of a protected instance property.
return this.protectedProp;
};

Javascript AA_PrivateClass_
public private

6.3.9 JavaScript

JSDoc EcmaScript 4

JavaScript

ES4 JavaScript JsDoc

ES4

196 Chapter 6. Javascript -


Google

JavaScript 5
{null} {undefined}
{boolean} {number}
{string}
{Object}
{Function} @constructor JSDoc
@interface JSDoc
{EventTarget}
EventTarget
null
{goog.events.EventType}
, @enum JSDoc
goog.events.EventType
ES4

{Array.<string>}
Java
{Object.<string,
number>}

{(number|boolean)} A B {(number,
boolean)}

{number|boolean} {(number||boolean)}
{function(): (number|boolean)}
{?number} {number?
syntactic sugar }

{!Object} null {Object!


}
{{myNum: number,
myObject}} myNum number myObject

length Array.
<{length}>
{function(string,
boolean)}

{function(): number}

{function(this:goog.ui.
6.3. Javascript 197
this Menu, string)}
Google

198 Chapter 6. Javascript -


Google

JavaScript

number
1
1.0
-5
1e5
Math.PI

Number Number
new Number(true)

string
'Hello'
"World"
String(42)

String String
new String('Hello')
new String(42)

boolean Boolean
true
false
Boolean(0)

Boolean Boolean
new Boolean(true)

RegExp
new RegExp('hello')
/world/g

Date
new Date
new Date()

null
null

undefined
undefined

void
function f() {
return;
6.3. Javascript } 199

Array
['foo', 0.3, null]
Google

/** @type {number} */ (x)

Javascript

/**
*
* @param {Object} value
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {Object}
* @private
*/
this.myValue_ = value;
}

myValue_ null myValue_ null, :

/**
* null
* @param {!Object} value
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {!Object}
* @private
*/
this.myValue_ = value;
}

MyClass null

undefined

200 Chapter 6. Javascript -


Google

/**
*
* @param {Object=} opt_value
* @constructor
*/
function MyClass(opt_value) {
/**
* Some value.
* @type {Object|undefined}
* @private
*/
this.myValue_ = opt_value;
}

myValue_ null undefined

: opt_value {Object=} {Object|undefined}


undefined undefined

/**
*
* @param {!Object} nonNull null
* @param {Object} mayBeNull null
* @param {!Object=} opt_nonNull null
* @param {Object=} opt_mayBeNull null
*/
function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) {
// ...
};

/**
* @param {string} tagName
* @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents
* @return {!Element}
*/
goog.createElement = function(tagName, contents) {
...
};

@typedef

6.3. Javascript 201


Google

/** @typedef {(string|Element|Text|Array.<Element>|Array.<Text>)} */


goog.ElementContent;

/**
* @param {string} tagName
* @param {goog.ElementContent} contents
* @return {!Element}
*/
goog.createElement = function(tagName, contents) {
...
};

this this
this

/**
* @param {function(this:T, ...)} fn
* @param {T} thisObj
* @param {...*} var_args
* @template T
*/
goog.bind = function(fn, thisObj, var_args) {
...
};
//
goog.bind(function() { this.someProperty; }, new SomeClass());
// this
goog.bind(function() { this.someProperty; });

6.3.10

JSDoc

c++ JSDoc

//

202 Chapter 6. Javascript -


Google

JSDoc JavaDoc JSDoc

/**
* A JSDoc comment should begin with a slash and 2 asterisks.
* Inline tags should be enclosed in braces like {@code this}.
* @desc Block tags should always start on their own line.
*/

JSDoc

/**
* Illustrates line wrapping for long param/return descriptions.
* @param {string} foo This is a param with a description too long to fit in
* one line.
* @return {number} This returns something that has a description too long to
* fit in one line.
*/
project.MyClass.prototype.method = function(foo) {
return 5;
};

@fileoverview

/**
* This is NOT the preferred indentation method.
* @param {string} foo This is a param with a description too long to fit in
* one line.
* @return {number} This returns something that has a description too long to
* fit in one line.
*/
project.MyClass.prototype.method = function(foo) {
return 5;
};

JSDoc HTML

JavaDoc , JSDoc HTML <code> <pre> <tt> <strong> <ul> <ol>


<li> <a>

6.3. Javascript 203


Google

JSDoc

/**
* Computes weight based on three factors:
* items sent
* items received
* last timestamp
*/

Computes weight based on three factors: items sent items received items received last␣
,→ timestamp

/**
* Computes weight based on three factors:
* <ul>
* <li>items sent
* <li>items received
* <li>last timestamp
* </ul>
*/

JavaDoc doc

/**
* @fileoverview Description of file, its uses and information
* about its dependencies.
*/

Class

/**
* Class making something fun and easy.
* @param {string} arg1 An argument that makes this more interesting.
(continues on next page)

204 Chapter 6. Javascript -


Google

(continued from previous page)

* @param {Array.<number>} arg2 List of numbers to be processed.


* @constructor
* @extends {goog.Disposable}
*/
project.MyClass = function(arg1, arg2) {
// ...
};
goog.inherits(project.MyClass, goog.Disposable);

/**
* Operates on an instance of MyClass and returns something.
* @param {project.MyClass} obj Instance of MyClass which leads to a long
* comment that needs to be wrapped to two lines.
* @return {boolean} Whether something occured.
*/
function PR_someMethod(obj) {
// ...
}

/** @constructor */
project.MyClass = function() {
/**
* Maximum number of things per pane.
* @type {number}
*/
this.someProperty = 4;
}

JSDoc

6.3. Javascript 205


Google

@author @author user-


[email protected] (first @fileoverview
last)

/**
* @fileoverview␣
,→Utilities for␣
,→handling textareas.
* @author kuth@google.
,→com (Uthur Pendragon)
*/

@code {@code }

/**
• Moves to
the next
position
in the
selection.
• Throws
{@code
goog.iter.StopIteration}
when it
• passes the
end of the
range.
• @return
{Node}
The node
at the next
position.
*/
goog.dom.RangeIterator.prototype.next
= function() {
//
};

Continued on next page

206 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@const @const @const {type}


@const
/** @const \*/ var MY_ js
,→ BEER = 'stout';
/**
* My namespace's␣ @const
,→ favorite kind of␣
,→ beer. @const
* @const {string}
*/
mynamespace.MY_BEER =
,→ 'stout';

/** @const \*/ MyClass.


,→ MY_BEER = 'stout';

/**
* Initializes the␣
,→ request.
* @const
*/
mynamespace.Request.
,→ prototype.initialize␣
,→ = function() {
// This method␣
,→ cannot be overriden␣
,→ in a subclass.
}

@constructor @constructor

/**
* A rectangle.
* @constructor
*/
function GM_Rect() {
...
}

Continued on next page

6.3. Javascript 207


Google

Table 1 – continued from previous page

@define @define {Type} description


--define='goog.
/** @define {boolean}␣ userAgent.ASSUME_IE=true'
,→ */ goog.userAgent.ASSUME_IE
var TR_FLAGS_ENABLE_ true
,→ DEBUG = true;

/** @define {boolean}␣


,→ */
goog.userAgent.ASSUME_
,→ IE = false;

@deprecated @deprecated Description

/**
* Determines whether a␣
,→ node is a field.
* @return {boolean}␣
,→ True if the contents␣
,→ of
* the element are␣
,→ editable, but the␣
,→ element
* itself is not.
* @deprecated Use␣
,→ isField().
*/
BN_EditUtil.
,→ isTopEditableField =␣
,→ function(node) {
// ...
};

Continued on next page

208 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@dict @dict Description ( Foo) @dict


Foo
/**
* @constructor
* @dict
*/
function Foo(x) {
this['x'] = x;
}
var obj = new Foo(123);
var num = obj.x; //␣
,→ warning
(/** @dict \*/ { x: 1 }
,→ ).x = 123; //␣
,→ warning

@enum @enum {Type}

/**
* Enum for tri-state␣
,→ values.
* @enum {number}
*/
project.TriState = {
TRUE: 1,
FALSE: -1,
MAYBE: 0
};

Continued on next page

6.3. Javascript 209


Google

Table 1 – continued from previous page

@export @export
--generate_exports
/** @export */
foo.MyPublicClass. goog.exportSymbol('foo.MyPublicClass.
,→ prototype. ,→ prototype.myPublicMethod',
,→ myPublicMethod =␣ foo.MyPublicClass.prototype.
,→ function() { ,→ myPublicMethod);
// ... @export
};
1. //javascript/closure/base.js ,

2. goog.exportSymbol goog.
exportProperty

@expose @expose

/** @expose */
@expose
MyClass.prototype.exposedProperty
= 3;
@extends @extends Type @extends @constructor
{Type}

/**
• Immutable
empty node
list.

@constructor
• @extends
goog.ds.BasicNodeList
*/
goog.ds.EmptyNodeList = function() {

};
Continued on next page

210 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@externs @externs

/**

@fileoverview
This is an
externs file.
• @externs
*/
var document;
@fileoverview @fileoverview Description

/**

@fileoverview
Utilities for
doing
things that
require this
very long
• but not
indented
comment.
• @author
[email protected]
(Uthur
Pendragon)
*/

Continued on next page

6.3. Javascript 211


Google

Table 1 – continued from previous page

@implements @implements Type @imple- @constructor


ments {Type}

/**
• A shape.
• @interface
*/
function Shape() {};
Shape.prototype.draw =
function() {};
/**
• @constructor
• @implements
{Shape}
*/
function Square() {};
Square.prototype.draw =
function() {

};
@inheritDoc @inheritDoc @override

/** @inheritDoc */
project.SubClass. @inheritDoc @override
,→ prototype.toString()
,→ {
// ...
};

Continued on next page

212 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@interface @interface

/**
* A shape.
* @interface
*/
function Shape() {};
Shape.prototype.draw =␣
,→function() {};

/**
* A polygon.
* @interface
* @extends {Shape}
*/
function Polygon() {};
Polygon.prototype.
,→getSides =␣
,→function() {};

@lends @lends objectName @lends


{objectName}

goog.object.extend(
Button.prototype, @type {Foo} Foo
/** @lends {Button. @lends {Foo} Foo
,→prototype} */ { .
isButton:␣ JSDoc Toolkit docs
,→function() { return␣
,→true; }
});

Continued on next page

6.3. Javascript 213


Google

Table 1 – continued from previous page

@license or @pre- @license Description @licenseor @preserve


serve
/**
* @preserve Copyright␣
,→2009 SomeThirdParty.
* Here is the full␣
,→license text and␣
,→copyright
* notice for this file.
,→ Note that the␣
,→notice can span␣
,→several
* lines and is only␣
,→terminated by the␣
,→closing star and␣
,→slash:
*/

@noalias @noalias

/** @noalias */
function Range() {}

@nosideeffects @nosideeffects

/** @nosideeffects */
function␣
,→noSideEffectsFn1() {
// ...
};
/** @nosideeffects */
var noSideEffectsFn2 =␣
,→function() {
// ...
};
/** @nosideeffects */
a.prototype.
,→noSideEffectsFn3 =␣
,→function() {
// ...
};

Continued on next page

214 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@override @override

/**
* @return {string}␣
,→ Human-readable␣
,→ representation of␣
,→ project.SubClass.
* @override
*/
project.SubClass.
,→ prototype.toString()
,→ {
// ...
};

@param @param {Type} varname


Description

/**
* Queries a Baz for␣
,→ items.
* @param {number}␣
,→ groupNum Subgroup id␣
,→ to query.
* @param
,→ {string|number|null}␣
,→ term An itemName,
* or itemId, or␣
,→ null to search␣
,→ everything.
*/
goog.Baz.prototype.
,→ query =␣
,→ function(groupNum,␣
,→ term) {
// ...
};

Continued on next page

6.3. Javascript 215


Google

Table 1 – continued from previous page

@private @private @private {type}


@private
/**
* Handlers that are␣
,→listening to this␣
,→logger.
* @private {!Array.
,→<Function>}
*/
this.handlers\_ = [];

@protected @protected @protected ‘‘ <http:


{type} //google-styleguide.googlecode.com/svn/trunk/
javascriptguide.xml#Visibility__private_and_
/** protected_fields_>‘‘_
* Sets the component's␣
,→root element to the␣
,→given element. ␣
,→Considered
* protected and final.
* @param {Element}␣
,→element Root element␣
,→for the component.
* @protected
*/
goog.ui.Component.
,→prototype.
,→setElementInternal =␣
,→function(element) {
// ...
};

Continued on next page

216 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@return @return {Type} Description

/** true false


* @return {string} The␣ @return
,→hex ID of the last␣
,→item.
*/
goog.Baz.prototype.
,→getLastId =␣
,→function() {
// ...
return id;
};

@see @see Link

/**
* Adds a single item,␣
,→recklessly.
* @see #addSafely
* @see goog.Collect
* @see goog.
,→RecklessAdder#add
...

Continued on next page

6.3. Javascript 217


Google

Table 1 – continued from previous page

@struct @struct Description Foo @struct


Foo Foo
/**
* @constructor
* @struct
*/
function Foo(x) {
this.x = x;
}
var obj = new Foo(123);
var num = obj['x']; //
,→ warning
obj.y = "asdf"; //␣
,→ warning

Foo.prototype = /**␣
,→ @struct */ {
method1: function()
,→ {}
};
Foo.prototype.method2␣
,→ = function() {}; //␣
,→ warning

@supported @supported Description

/**
* @fileoverview Event␣
,→ Manager
* Provides an␣
,→ abstracted interface␣
,→ to the
* browsers' event␣
,→ systems.
* @supported So far␣
,→ tested in IE6 and␣
,→ FF1.5
*/

Continued on next page

218 Chapter 6. Javascript -


Google

Table 1 – continued from previous page

@suppress @suppress {warn- |


ing1|warning2}

/**
* @suppress
,→ {deprecated}
*/
function f() {

,→ deprecatedVersionOfF();
,→

@template @template

/**
* @param
,→ {function(this:T, ...
,→ )} fn
* @param {T} thisObj
* @param {...*} var_
,→ args
* @template T
*/
goog.bind =␣
,→ function(fn, thisObj,
,→ var_args) {
...
};

Continued on next page

6.3. Javascript 219


Google

Table 1 – continued from previous page

@this @this Type @this {Type}


this
pinto.chat.
,→ RosterWidget.extern(
,→ 'getRosterElement',
/**
* Returns the roster␣
,→ widget element.
* @this pinto.chat.
,→ RosterWidget
* @return {Element}
*/
function() {
return this.
,→ getWrappedComponent_
,→ ().getElement();
});

@type @type Type @type {Type}

/**
• The mes-
sage hex
ID.
• @type
{string}
*/
var hexId = hexId;
@typedef @typedef

/** @typedef
,→ {(string|number)} */
goog.NumberLike;
/** @param {goog.
,→ NumberLike} x A␣
,→ number or a string.␣
,→ */
goog.readNumber =␣
,→ function(x) {
...
}

220 Chapter 6. Javascript -


Google

JSDoc JSDoc Toolkit

• @augments

• @argument

• @borrows

• @class

• @constant

• @constructs

• @default

• @event

• @example

• @field

• @function

• @ignore

• @inner

• @link

• @memberOf

• @name

• @namespace

• @property

• @public

• @requires

• @returns

• @since

• @static

• @version

6.3.11 goog.provide

6.3. Javascript 221


Google

goog.provide('namespace.MyClass');

goog.provide('namespace.MyClass');
goog.provide('namespace.MyClass.Enum');
goog.provide('namespace.MyClass.InnerClass');
goog.provide('namespace.MyClass.TypeDef');
goog.provide('namespace.MyClass.CONSTANT');
goog.provide('namespace.MyClass.staticMethod');

goog.provide('foo.bar');
goog.provide('foo.bar.method');
goog.provide('foo.bar.CONSTANT');

6.3.12

JS Closure Compiler

6.3.13

JavaScript

True False

false

• null

• undefined

• 0

true

• 0

• []

• {}

222 Chapter 6. Javascript -


Google

while (x != null) {

x 0 false

while (x) {

null

if (y != null && y != '') {

if (y) {

• Boolean( 0 ) == true 0 != true

• 0 != null 0 == [] 0 == false

• Boolean(null) == false null != true null != false

• Boolean(undefined) == false undefined != true undefined != false

• Boolean([]) == true [] != true [] == false

• Boolean({}) == true {} != true {} != false

if (val != 0) {
return foo();
} else {
return bar();
}

return val ? foo() : bar();

HTML

var html = '<input type="checkbox"' +


(isChecked ? ' checked' : '') +
(isEnabled ? '' : ' disabled') +
' name="foo">';

6.3. Javascript 223


Google

&& ||

|| default

/** @param {*=} opt_win */


function foo(opt_win) {
var win;
if (opt_win) {
win = opt_win;
} else {
win = window;
}
// ...
}

/** @param {*=} opt_win */


function foo(opt_win) {
var win = opt_win || window;
// ...
}

&&

if (node) {
if (node.kids) {
if (node.kids[index]) {
foo(node.kids[index]);
}
}
}

if (node && node.kids && node.kids[index]) {


foo(node.kids[index]);
}

var kid = node && node.kids && node.kids[index];


if (kid) {
foo(kid);
}

224 Chapter 6. Javascript -


Google

node && node.kids && node.kids[index] && foo(node.kids[index]);

length
O(n) length O(n^2)

var paragraphs = document.getElementsByTagName('p');


for (var i = 0; i < paragraphs.length; i++) {
doSomething(paragraphs[i]);
}

var paragraphs = document.getElementsByTagName('p');


for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
doSomething(paragraph);
}

( false )

firstChild nextSibling

var parentNode = document.getElementById('foo');


for (var child = parentNode.firstChild; child; child = child.nextSibling) {
doSomething(child);
}

6.3. Javascript 225


Google

226 Chapter 6. Javascript -


CHAPTER 7

TypeScript

7.1

7.1.1

RFC 2119

7.1.2

2021 09 02

• TinkerRobot

Google TypeScript Style Guide

227
Google

TypeScript

• 2021 09 02 TinkerRobot

7.2

7.2.1

TypeScript ASCII (
[\)\w]+

UpperCamelCase
lowerCamelCase
CONSTANT_CASE
#ident

loadHttpUrl loadHTTPURL
XMLHttpRequest

$ $
Observable

Array<T> T
UpperCamelCase

Closure testSuites xUnit _


testX_whenY_doesZ()

228 Chapter 7. TypeScript


Google

_ _

const [a, , b] = [1, 5, 10]; // a <- 1, b <- 10

lowerCamelCase snake_case

import * as fooBar from './foo_bar';

• jQuery $

• three.js THREE

CONSTANT_CASE
deep frozen

const UNIT_SUFFIXES = {
'milliseconds': 'ms',
'seconds': 's',
};
// UNIT_SUFFIXES
//
//

class Foo {
private static readonly MY_SPECIAL_NUMBER = 5;

bar() {
return 2 * Foo.MY_SPECIAL_NUMBER;
}
}

7.2. 229
Google

const readonly

const {Foo} = SomeType;


const CAPACITY = 5;

class Teapot {
readonly BrewStateEnum = BrewStateEnum;
readonly CAPACITY = CAPACITY;
}

TypeScript
Testing Blog

• _

• opt_

– 1.5. #include

• IMyInterface
MyFooInterface
TodoItem JSON
TodoItemStorage

• Observable $

API
i j

230 Chapter 7. TypeScript


Google

7.2.2

UTF-8

ASCII Unicode ∞
Unicode \u221e

//
const units = 'µs';

//
const output = '\ufeff' + content; // Byte Order Mark BOM

//
const units = '\u03bcs'; // Greek letter mu, 's'

//
const output = '\ufeff' + content;

7.2.3

JSDoc

TypesScript JSDoc /** ... */ // ... /* ... */

• /** JSDoc */

• //

JSDoc

JSDoc

JSDoc JavaScript JavaScript

/** JSDoc */

/** JSDoc */

TypeScript

@param @return implements enum private


@implements @enum @private

7.2. 231
Google

@override

TypeScript @override @override

//
/** @param fooBarService Foo Bar */

@param @return

/**
* POST
* @param amountLitres
*/
brew(amountLitres: number, logger: Logger) {
// ...
}

class Foo {
constructor(private readonly bar: Bar) { }
}

Foo Bar bar

JSDoc @param

/** */
class ParamProps {
/**
* @param percolator
* @param beans
*/
constructor(
(continues on next page)

232 Chapter 7. TypeScript


Google

(continued from previous page)

private readonly percolator: Percolator,


private readonly beans: CoffeeBean[]) {}
}

/** */
class OrdinaryClass {
/** brew() */
nextBean: CoffeeBean;

constructor(initialBean: CoffeeBean) {
this.nextBean = initialBean;
}
}

/* */

//
new Percolator().brew(/* amountLitres= */ 5);

// brew
new Percolator().brew({amountLitres: 5});

/** {@link CoffeeBrewer} */


export class Percolator implements CoffeeBrewer {
/**
*
* @param amountLitres
*/
brew(amountLitres: number) {
//
// TODO(b/12345):
}
}

@Component JSDoc JSDoc

JSDoc

7.2. 233
Google

// JSDoc @Component FooComponent


@Component({
selector: 'foo',
template: 'bar',
})
/** "bar" */
export class FooComponent {}

JSDoc

/** "bar" */
@Component({
selector: 'foo',
template: 'bar',
})
export class FooComponent {}

7.3

7.3.1

• TypeScript public public


readonly public

class Foo {
public bar = new Bar(); // public

constructor(public readonly baz: Baz) {} // readonly ␣


,→ baz public public
}

class Foo {
bar = new Bar(); // public

constructor(public baz: Baz) {} // ␣


,→ public
}

234 Chapter 7. TypeScript


Google

7.3.2

//
const x = new Foo;

//
const x = new Foo();

ES2015

//
class UnnecessaryConstructor {
constructor() {}
}

//
class UnnecessaryConstructorOverride extends Base {
constructor(value: number) {
super(value);
}
}

//
class DefaultConstructor {
}

//
class ParameterProperties {
constructor(private myService) {}
}

//
class ParameterDecorators {
constructor(@SideEffectDecorator myService) {}
}

//
class NoInstantiation {
(continues on next page)

7.3. 235
Google

(continued from previous page)

private constructor() {}
}

7.3.3

#private

#private

//
class Clazz {
#ident = 1;
}

TypeScript

//
class Clazz {
private ident = 1;
}

TypeScipt JavaScript ES2015


TypeScript ES2015

readonly

readonly

TypeScript

//
class Foo {
private readonly barService: BarService;

constructor(barService: BarService) {
this.barService = barService;
}
}

236 Chapter 7. TypeScript


Google

//
class Foo {
constructor(private readonly barService: BarService) {}
}

JSDoc @param

//
class Foo {
private readonly userList: string[];
constructor() {
this.userList = [];
}
}

//
class Foo {
private readonly userList: string[] = [];
}

template AngularJS con-


troller private

public protected Angular


Polymer public AngularJS protected

TypeScript obj['foo']

private

obj['foo'] TypeScript

7.3. 237
Google

class Foo {
constructor(private readonly someService: SomeService) {}

get someMember(): string {


return this.someService.someVariable;
}

set someMember(newValue: string) {


this.someService.someVariable = newValue;
}
}

internal wrapped

public
readonly

class Foo {
private wrappedBar = '';
get bar() {
return this.wrappedBar || 'bar';
}

set bar(wrapped: string) {


this.wrappedBar = wrapped.trim();
}
}

class Bar {
private barInternal = '';
// bar public

get bar() {
return this.barInternal;
}

set bar(value: string) {


this.barInternal = value;
}
}

238 Chapter 7. TypeScript


Google

7.3.4

TypeScript String Boolean Number


new Boolean(false) true

//
const s = new String('hello');
const b = new Boolean(false);
const n = new Number(5);

//
const s = 'hello';
const b = false;
const n = 5;

7.3.5

TypeScript Array() new

//
const a = new Array(2); // 2 [undefined,␣
,→ undefined]
const b = new Array(2, 3); // 2, 3 [2, 3]

from

const a = [2];
const b = [2, 3];

// Array(2)
const c = [];
c.length = 2;

// [0, 0, 0, 0, 0]
Array.from<number>({length: 5}).fill(0);

7.3.6

TypeScript String() Boolean() new


!!

const bool = Boolean(false);


const str = String(aNumber);
(continues on next page)

7.3. 239
Google

(continued from previous page)

const bool2 = !!str;


const str2 = `result: ${ bool2}`;

string

Number()
NaN

Tip: Number('') Number(' ') Number('\t') 0 NaN Number('Infinity')


Number('-Infinity') Infinity -Infinity

const aNumber = Number('123');


if (isNaN(aNumber)) throw new Error(...); //
NaN
assertFinite(aNumber, ...); //

+
+

//
const x = +y;

parseInt parseFloat

12 dwarves 12

const n = parseInt(someString, 10); //


const f = parseFloat(someString); //

parseInt

if (!/^[a-fA-F0-9]+$/.test(someString)) throw new Error(...);


// 16
// tslint:disable-next-line:ban
const n = parseInt(someString, 16); // parseInt

Number() Math.floor Math.trunc

let f = Number(someString);
if (isNaN(f)) handleError();
f = Math.floor(f);

240 Chapter 7. TypeScript


Google

if for while boolean

//
const foo: MyInterface|null = ...;
if (!!foo) {...}
while (!!foo) {...}

//
const foo: MyInterface|null = ...;
if (foo) {...}
while (foo) {...}

// 0
if (arr.length > 0) {...}

//
if (arr.length) {...}

7.3.7

const let const var

const foo = otherValue; // foo const


let bar = someValue; // bar let

const let var


JavaScript bug TypeScript
var

//
var foo = someValue;

7.3.8

new Error() Error()


new

//
throw new Error('Foo is not a valid bar.');
(continues on next page)

7.3. 241
Google

(continued from previous page)

//
throw Error('Foo is not a valid bar.');

7.3.9

for (... in ...)


for (... in ...)

//
for (const x in someObj) {
// x someObj
}

if for (... of Object.keys(.


..))

//
for (const x in someObj) {
if (!someObj.hasOwnProperty(x)) continue;
// x someObj
}

//
for (const x of Object.keys(someObj)) { // for _of_
// x someObj
}

//
for (const [key, value] of Object.entries(someObj)) { // for _of_

// key someObj
}

7.3.10

for (... in ...)


string

//
for (const x in someArray) {
(continues on next page)

242 Chapter 7. TypeScript


Google

(continued from previous page)

// x ( string )
}

for (... of someArr) for

//
for (const x of someArr) {
// x
}

//
for (let i = 0; i < someArr.length; i++) {
// for/of
const x = someArr[i];
// ...
}

//
for (const [i, x] of someArr.entries()) {
//
}

Array.prototype.forEach Set.prototype.forEach Map.prototype.forEach

//
someArr.forEach((item, index) => {
someFn(item, index);
});

let x: string|null = 'abc';


myArray.forEach(() => { x.charAt(0); });

x null
.forEach() () => { x.charAt(0); }
x null
for-of

7.3. 243
Google

7.3.11

[...foo] {...bar}

const foo = {
num: 1,
};

const foo2 = {
...foo,
num: 5,
};

const foo3 = {
num: 5,
...foo,
}

// foo2 1 5
foo2.num === 5;

// foo3 5 1
foo3.num === 1;

null undefined

//
const foo = {num: 7};
const bar = {num: 5, ...(shouldUseFoo && foo)}; // undefined

// length {0: 'a', 1: 'b', 2: 'c'}


const fooStrings = ['a', 'b', 'c'];
const ids = {...fooStrings};

//
const foo = shouldUseFoo ? {num: 7} : {};
const bar = {num: 5, ...foo};

//
const fooStrings = ['a', 'b', 'c'];
const ids = [...fooStrings, 'd', 'e'];

244 Chapter 7. TypeScript


Google

7.3.12 /

//
for (let i = 0; i < x; i++) {
doSomethingWith(i);
andSomeMore();
}
if (x) {
doSomethingWithALongMethodName(x);
}

//
if (x)
x.doFoo();
for (let i = 0; i < x; i++)
doSomethingWithALongMethodName(i);

if

//
if (x) x.doFoo();

7.3.13 switch

switch default

//
switch (x) {
case Y:
doSomethingElse();
break;
default:
//
}

case ...

//
switch (x) {
case X:
doSomething();
//
case Y:
(continues on next page)

7.3. 245
Google

(continued from previous page)

// ...
}

//
switch (x) {
case X:
case Y:
doSomething();
break;
default: //
}

7.3.14

=== !==
JavaScript JavaScript

//
if (foo == 'bar' || baz != bam) {
//
}

//
if (foo === 'bar' || baz !== bam) {
//
}

null == != null undefined

//
if (foo == null) {
// foo null undefined
}

7.3.15

function foo() { ... }

246 Chapter 7. TypeScript


Google

const x = function() {...}; TypeScript


const

this

//
function foo() { ... }

//
//
foo = () => 3; //

//
const foo = function() { ... }

function foo() {}
doSomethingWith(function() {});

interface SearchFunction {
(source: string, subString: string): boolean;
}

const fooSearch: SearchFunction = (source, subString) => { ... };

7.3.16

ES6 function

//
bar(() => { this.doSomething(); })

//
bar(function() { ... })

this function
this this

7.3. 247
Google

//
function someFunction() {
// => { }
const receipts = books.map((b: Book) => {
const receipt = payMoney(b.price);
recordTransaction(receipt);
return receipt;
});

//
const longThings = myValues.filter(v => v.length > 1000).map(v => String(v));

function payMoney(amount: number) {


// this
}
}

// { ... }
myPromise.then(v => console.log(v));

//
myPromise.then(v => {
console.log(v);
});

//
const transformed = [1, 2, 3].map(v => {
const intermediate = someComplicatedExpr(v);
const more = acrossManyLines(intermediate);
return worthWrapping(more);
});

this

this this
this

//
function clickHandler() {
// this
this.textContent = 'Hello';
(continues on next page)

248 Chapter 7. TypeScript


Google

(continued from previous page)

// this document.body
document.body.onclick = clickHandler;

//
document.body.onclick = () => { document.body.textContent = 'hello'; };

//
const setTextFn = (e: HTMLElement) => { e.textContent = 'hello'; };
document.body.onclick = setTextFn.bind(null, document.body);

this this

const handler = (x) => { this.listener(x); };


const handler = this.listener; handler(x);

Tip:

//
class DelayHandler {
constructor() {
// this
// this DelayHandler
setTimeout(this.patienceTracker, 5000);
}
private patienceTracker() {
this.waitedPatiently = true;
}
}

//
class DelayHandler {
constructor() {
// this
setTimeout(this.patienceTracker, 5000);
(continues on next page)

7.3. 249
Google

(continued from previous page)

}
private patienceTracker = () => {
this.waitedPatiently = true;
}
}

// this
class DelayHandler {
constructor() {
//
setTimeout(() => {
this.patienceTracker();
}, 5000);
}
private patienceTracker() {
this.waitedPatiently = true;
}
}

this

//
class Component {
onAttached() {
//
this.addEventListener('click', () => {
this.listener();
});
// this.listener
window.addEventListener('onbeforeunload', this.listener);
}
onDetached() {
// window this.listener
// this this
window.removeEventListener('onbeforeunload', this.listener);
}
// this
private listener = () => {
confirm('Do you want to exit the page?');
(continues on next page)

250 Chapter 7. TypeScript


Google

(continued from previous page)

}
}

bind

// bind
class Component {
onAttached() {
//
window.addEventListener('onbeforeunload', this.listener.bind(this));
}
onDetached() {
// bind
window.removeEventListener('onbeforeunload', this.listener.bind(this));
}
private listener() {
confirm('Do you want to exit the page?');
}
}

7.3.17

ASI
Bug ASI clang-format

7.3.18 @ts-ignore

@ts-ignore

@ts-ignore
any any

7.3.19

x as SomeType y!

//
(x as Foo).foo();

y!.bar();

7.3. 251
Google

//

// Foo
if (x instanceof Foo) {
x.foo();
}

if (y) {
y.bar();
}

//

// x Foo
(x as Foo).foo();

// y null
y!.bar();

as

//
const x = (<Foo>z).length;
const y = <Foo>z.length;

//
const x = (z as Foo).length;

: Foo as Foo
Bug

252 Chapter 7. TypeScript


Google

interface Foo {
bar: number;
baz?: string; // bam baz
}

const foo = {
bar: 123,
bam: 'abc', //
} as Foo;

function func() {
return {
bar: 123,
bam: 'abc', //
} as Foo;
}

7.3.20

//
interface Foo {
memberA: string;
memberB: number;
}

//
interface Foo {
memberA: string,
memberB: number,
}

//
type SomeTypeAlias = {
memberA: string,
memberB: number,
};

let someProperty: {memberC: string, memberD: number};

7.3. 253
Google

//
//
console.log(x['someField']);
console.log(x.someField);

//
declare interface ServerInfoJson {
appVersion: string;
user: UserJson;
}
const data = JSON.parse(serverResponse) as ServerInfoJson;
console.log(data.appVersion); //

//
import {method1, method2} from 'utils';
class A {
readonly utils = {method1, method2};
}

//
import * as utils from 'utils';
class A {
readonly utils = utils;
}

Web

7.3.21

enum const enum TypeScript


const enum JavaScript

254 Chapter 7. TypeScript


Google

7.3.22 debugger

debugger

//
function debugMe() {
debugger;
}

7.3.23

@ @MyDecorator

• Angular @Component @NgModule

• Polymer @property

TC39
Bug

/** JSDoc */
@Component({...}) //
class MyComp {
@Input() myField: string; //

@Input()
myOtherField: string; //
}

7.4

7.4.1

TypeScript . ..
root/path/to/file

./foo path/to/foo

../../../

7.4. 255
Google

import {Symbol1} from 'google3/path/from/root';


import {Symbol2} from '../parent/file';
import {Symbol3} from './sibling';

TypeScript namespace module

TypeScript ES6
import {foo} from 'bar'

namespace Foo { ... }

require import x = require('...'); ES6

//
namespace Rocket {
function launch() { ... }
}

// <reference>
/// <reference path="..."/>

// require()
import x = require('mydep');

Tip: TypeScript module module Foo { ...


} ES6

7.4.2

// Use named exports:


export class Foo { ... }

//
export default class Foo { ... }

256 Chapter 7. TypeScript


Google

//
import Foo from './bar'; //
import Bar from './bar'; //

foo.ts

//
const foo = 'blah';
export default foo;

bar.ts

//
import {fizz} from './foo';

error TS2614: Module '"./foo"' has no exported member 'fizz'


bar.ts

// fizz
import fizz from './foo';

fizz === foo

//
export default class Foo {
static SOME_CONSTANT = ...
static someHelpfulFunction() { ... }
...
}

Foo

//
export const SOME_CONSTANT = ...
export function someHelpfulFunction()
export class Foo {
// Foo
}

7.4. 257
Google

TypeScript
API

export let

//
export let foo = 3;
// ES6 foo foo

// TypeScript foo
window.setTimeout(() => {
foo = 4;
}, 1000 /* ms */);

//
let foo = 3;
window.setTimeout(() => {
foo = 4;
}, 1000 /* ms */);
//
export function getFoo() { return foo; };

function pickApi() {
if (useOtherApi()) return OtherApi;
return RegularApi;
}
export const SomeApi = pickApi();

//
export class Container {
static FOO = 1;
(continues on next page)

258 Chapter 7. TypeScript


Google

(continued from previous page)

static bar() { return 1; }


}

//
export const FOO = 1;
export function bar() { return 1; }

7.4.3

ES6 TypeScript

import * as foo from '...'; TypeScript


import {SomeThing} from '...'; TypeScript
import SomeThing from '...';
import '...';

//
import * as ng from '@angular/core';
import {Foo} from './foo';

//
import Button from 'Button';

//
import 'jasmine';
import '@polymer/paper-button';

API

Jasmine describe it

7.4. 259
Google

//
import {TableViewItem, TableViewHeader, TableViewRow, TableViewModel,
TableViewRenderer} from './tableview';
let item: TableViewItem = ...;

//
import * as tableview from './tableview';
let item: tableview.Item = ...;

import * as testing from './testing';

//
//
//
testing.describe('foo', () => {
testing.it('bar', () => {
testing.expect(...);
testing.expect(...);
});
});

//
import {describe, it, expect} from './testing';

describe('foo', () => {
it('bar', () => {
expect(...);
expect(...);
});
});
...

import {SomeThing as SomeOtherThing}

1.

2.

3. RxJS from
observableFrom

260 Chapter 7. TypeScript


Google

import type export type

import type ... from export type ... from

Tip: export type Foo = ...;

//
import type {Foo} from './foo';
export type {Bar} from './bar';

//
import {Foo} from './foo';
export {Bar} from './bar';

TypeScript
import type import
import type

import '...'

export type API import type export


type API
UserService
AjaxUserService

7.4.4

products checkout backend


views models controllers

7.5

7.5.1

TypeScript
google3
any

const x = 15; // x .

string number boolean RegExp new

7.5. 261
Google

// boolean
const x: boolean = true;

// Set
const x: Set<string> = new Set();

// TypeScript
const x = new Set<string>();

TypeScript

7.5.2 Null Undefined

TypeScript null undefined string | null


undefined null undefined

TypeScript undefined null


JavaScript API undefined Map.get DOM Google API
null Element.getAttribute null undefined

|null |undefined

|null |undefined

// undefined
type CoffeeResponse = Latte|Americano|undefined;

(continues on next page)

262 Chapter 7. TypeScript


Google

(continued from previous page)

class CoffeeService {
getLatte(): CoffeeResponse { ... };
}

// undefined
type CoffeeResponse = Latte|Americano;

class CoffeeService {
getLatte(): CoffeeResponse|undefined { ... };
}

//
type CoffeeResponse = Latte|Americano;

class CoffeeService {
getLatte(): CoffeeResponse {
return assert(fetchResponse(), 'Coffee maker is broken, file a ticket');
};
}

undefined

TypeScript ?

interface CoffeeOrder {
sugarCubes: number;
milk?: Whole|LowFat|HalfHalf;
}

function pourCoffee(volume?: Milliliter) { ... }

|undefined
{sugarCubes: 1} CoffeeOrder milk

|undefined

class MyClass {
field = '';
}

7.5. 263
Google

7.5.3

TypeScript

Mock

//
const foo: Foo = {
a: 123,
b: 'abc',
}

//
const badFoo = {
a: 123,
b: 'abc',
}

badFoo badFoo

badFoo Foo

interface Animal {
sound: string;
name: string;
}

function makeSound(animal: Animal) {}

/**
* 'cat' '{sound: string}'
*/
const cat = {
sound: 'meow',
};

/**
(continues on next page)

264 Chapter 7. TypeScript


Google

(continued from previous page)

* 'cat'
* TypeScript
* 'cat'
*/
makeSound(cat);

/**
* Horse
* 'horse' 'Animal'
*/
const horse: Animal = {
sound: 'niegh',
};

const dog: Animal = {


sound: 'bark',
name: 'MrPickles',
};

makeSound(dog);
makeSound(horse);

7.5.4

TypeScript

//
interface User {
firstName: string;
lastName: string;
}

//
type User = {
firstName: string,
lastName: string,
}

7.5. 265
Google

TypeScript

7.5.5 Array<T>

. T[]
Array<T>

Array<T>

readonly T[] ReadonlyArray<T>

//
const a: string[];
const b: readonly string[];
const c: ns.MyObj[];
const d: Array<string|number>;
const e: ReadonlyArray<string|number>;

//
const f: Array<string>; //
const g: ReadonlyArray<string>;
const h: {n: number, s: string}[]; //
const i: (string|number)[];
const j: readonly (string|number)[];

7.5.6 {[key: string]: number}

JavaScript

const fileSizes: {[fileName: string]: number} = {};


fileSizes['readme.txt'] = 541;

TypeScript

//
const users: {[key: string]: number} = ...;

//
const users: {[userName: string]: number} = ...;

TypeScript ES6 Map Set


JavaScript ES6
Map Set string

266 Chapter 7. TypeScript


Google

TypeScript Record<Keys, ValueType>

7.5.7

TypeScript Type-
Script Record Partial Readonly

TypeScript

• TypeScript

• /

• IDE
Pick<T, Keys>

TypeScript Pick<T, Keys> T

interface User {
shoeSize: number;
favoriteIcecream: string;
favoriteChocolate: string;
}

// FoodPreferences favoriteIcecream favoriteChocolate shoeSize


type FoodPreferences = Pick<User, 'favoriteIcecream'|'favoriteChocolate'>;

FoodPreferences

interface FoodPreferences {
favoriteIcecream: string;
(continues on next page)

7.5. 267
Google

(continued from previous page)

favoriteChocolate: string;
}

User FoodPreferences User FoodPrefences

interface FoodPreferences { /* */ }

interface User extends FoodPreferences {


shoeSize: number;
// User FoodPreferences
}

IDE

7.5.8 any

TypeScript any
any

any any

• unknown any

• Lint any

// JSON
declare interface MyUserJson {
name: string;
email: string;
}

//
type MyType = number|string;

//
function getTwoThings(): {something: number, other: string} {
// ...
return {something, other};
(continues on next page)

268 Chapter 7. TypeScript


Google

(continued from previous page)

// any
//
//
function nicestElement<T>(items: T[]): T {
// items
// T <T extends HTMLElement>
}

unknown any

any
unknown
unknown any

//
// null undefined val
//
const val: unknown = value;

//
const danger: any = value /* */;
danger.whoops(); //

Lint any

any Mock Lint


any

// BookService
// Mock
// tslint:disable-next-line:no-any
const mockBookService = ({get() { return mockBook; }} as any) as BookService;
//
// tslint:disable-next-line:no-any
const component = new MyComponent(mockBookService, /* unused ShoppingCart */ null as␣
,→ any);

7.5.9

Pair

7.5. 269
Google

//
interface Pair {
first: string;
second: string;
}

function splitInHalf(input: string): Pair {


// ...
return {first: x, second: y};
}

//
function splitInHalf(input: string): [string, string] {
// ...
return [x, y];
}

// :
const [leftHalf, rightHalf] = splitInHalf('my string');

function splitHostPort(address: string): {host: string, port: number} {


// ...
}

// :
const address = splitHostPort(userAddress);
use(address.port);

//
const {host, port} = splitHostPort(userAddress);

7.5.10

JavaScript

• String Boolean Number string boolean number

• Object {} object {} null


undefined object
symbol bigint

270 Chapter 7. TypeScript


Google

7.5.11

API API

7.6

7.6.1

1.

• any

• TypeScript

• .

• private

2.

JavaScript

• x as T <T>x

• Array<[number, number]> [number, number][]

3.

7.6. 271
Google

TypeScript

• Clousure TS

• google3

4.

Bug

272 Chapter 7. TypeScript

You might also like