中文版
中文版
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
• ReadTheDocs
• GitHub zh-google-styleguide
• release
Note:
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
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
3
Google
• Google -
2.1.1 0.1
Google , .
Google , . Google
, Google .
. , , .
, , , .
Google ,5 , .
. ,
.
, , ,
. , , Google
, . , ,
.
, . .
, , bug . , .
, Artistic License/GPL .
3.133 , ,
. Yang.Y , YuleFox .
4 Chapter 2. C++ -
Google
2.1.2 0.2
C++ . ,
C++ .
, , C++ . ,
.
. .
.
, . ,
.
C++ . C++ . ,
. , .
, .
Google .
: C++ , C++ .
2.2 1.
.cc .h . , main()
.cc .
Tip: self-contained, .h
.inc -inl.h
.
self-contained
platform-specific .inc
.h .cc
-inl.h
-inl.h
2.2. 1. 5
Google
.cc
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
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
• symbol include
•
.
• .
• #include.
• #include.
1.5. #include
2.2.4 1.4.
Tip: 10 .
, ,
.
, .
, , .
. , .
,
. ,
, 10 . ,
, !
: switch (
, switch ).
2.2. 1. 7
Google
, ;
. , . YuleFox :
, ,
). , ,
, .
Tip: , : ,C , C++ ,
.h, .h.
, UNIX .( ) ..
( ). , google-awesome-project/src/base/logging.h :
#include "base/logging.h"
1. dir2/foo2.h ( , )
2. C
3. C++
4. .h
5. .h
, google-awesome-project/src/foo/internal/fooserver.cc :
#include "foo/public/fooserver.h" //
8 Chapter 2. C++ -
Google
#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"
#include "foo/public/fooserver.h"
#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.
, , .
(YuleFox : ),
.
, Foo, .
, project1::Foo project2::Foo
.
namespace X {
inline namespace Y {
void foo();
} // namespace Y
} // namespace X
10 Chapter 2. C++ -
Google
• , gflags / ,
, :
// .h
namespace mynamespace {
//
//
class MyClass {
public:
...
void Foo();
};
} // namespace mynamespace
// .cc
namespace mynamespace {
//
void MyClass::Foo() {
...
}
} // namespace mynamespace
#include "a.h"
namespace 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
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);
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
f.DoSomething(i);
}
2.3.5 2.5.
bug constexpr
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,
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
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);
...
};
, 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
struct, class.
struct , , ,
. , . , , Initialize(),
Reset(), Validate() , .
, class . , class.
: .
2.4.5 3.5.
, . C++ , :
, ; , .
. ,
. , API. API
, .
, , .
, . ,
.
public . , .
20 Chapter 2. C++ -
Google
, 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 ,
.
. = .
<< . , .
2.4.9 3.9.
2.4.10 3.10.
, public .
2.4. 3. 23
Google
, , : ( typedef, using
), , , , , , , .
. ,
. .
2.4.11 (YuleFox)
1. ;
2. , , ,
;
3. , explicit;
4. , , private ;
5. struct;
7. , , , ;
8. Interface , , ,
, , , , protected;
9. , , , ;
10. ;
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.
(*pval)++ .
. .
, .
, const:
2.5. 4. 25
Google
• .
• .
2.5.4 4.4.
, ,
. .
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++ . . :
C++11 . auto , .
:
. int , . ,
, .
2.5. 4. 27
Google
Lambda . ,
Lambda , . ,
.
, , ,
. :
, C Java ,
.
, .
. , .
, , .
( Lambda )
. , ,
.
2.6 5. Google
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
,
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
>
cpplint.py .
>
cpplint.py , . , ,
. // NOLINT, // NOLINTNEXTLINE,
.
cpplint.py. ,
cpplint.py.
2.6.3 acgtyrant
1. , .
4. , , , .
2.7 6. C++
2.7.1 6.1.
Tip: const.
(*pval)++ . .
, NULL .
, .
, const:
30 Chapter 2. C++ -
Google
• null
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
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
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);
Tip: alloca().
. alloca() .
alloca() C++ . ,
, bugs: ,
.
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++
• 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 ( ) .
, , .
RTTI . ,
. RTTI .
RTTI . :
. ,
.
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.
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 .
, . .
, .
. . . ,
: , . :
<< , . .
printf , , . ,
, ?
2.7. 6. C++ 37
Google
, , , ? ,
, .
, , .
, printf + read/write.
2.7.11 6.11.
Tip: (++i) , .
, (++i) (i++) . (
) i . i ,
. , ?
C , , , for .
, , (i) (++) .
( ), . , ( ).
38 Chapter 2. C++ -
Google
. , ,
. ,
. , .
const , , ; .
, const:
• , const.
• const. const. ,
const , const const.
• , const.
mutable , , .
const :
, const . ! (Yang.Y :
const , , , .)
constexpr
constexpr, constexpr
2.7. 6. C++ 39
Google
constexpr
constexpr con-
stexpr
2.7.14 6.14.
C++ .
, int, .
int. int 32 , 32 . 64 ,
int64_t uint64_t.
, int64_t.
uint32_t , ,
. , . ,
.
size
40 Chapter 2. C++ -
Google
, , .
. , C , bug . :
, , !
2.7.15 6.15. 64
Tip: 64 32 . , , :
• , printf() 32 64 . C99
. , MSVC 7.1 , ,
( inttypes.h ):
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 ).
• , (Yang.Y : -
). 64 , int64_t/uint64_t
/ , 8 . 32 64 ,
. . gcc
__attribute__((packed)). MSVC #pragma pack() __declspec(align()) (Yule-
Fox , ).
• 64 LL ULL , :
2.7.16 6.16.
Tip: , , .
. , .
, C++ , C . ,
. const . .
, , (#define ).
, ( ) (
# , ## ). , .
42 Chapter 2. C++ -
Google
; , :
• .h .
• #define, #undef.
• #undef
• C++ , .
• ##
0, 0.0, .
( ) '\0', .
sizeof(varname) . sizeof(type)
Struct data;
Struct data; memset(&data, 0, sizeof(data));
Warning:
memset(&data, 0, sizeof(Struct));
2.7. 6. C++ 43
Google
Tip: auto
C++11 auto,
auto
vector<string> v;
...
auto s1 = v[0]; // v[0]
const auto& s2 = v[0]; // s2 v[0]
C++
auto
auto,
auto i = x.Lookup(key);
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
2.7.20 6.20.
Tip:
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:
9.7. .
46 Chapter 2. C++ -
Google
Lambda
• STL Lambdas
• Lambdas
• Lambdas
• format lambda
• 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
• : , ,
. .
• , .
, ,
• , .
. c++
.
, , , , SFINAE, sizeof
trick , , ,
• , , .
, ,
. .
, .
. ,
,
Tip: Boost .
Boost , , C++ .
Boost , , C++ , ,
,
Boost , ,
.
48 Chapter 2. C++ -
Google
, Boost
. :
• 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
• Multi-index : boost/multi_index
• Heap : boost/heap
Boost , .
C++ 11
C++11 ‘ <https://en.wikipedia.org/wiki/C%2B%2B11>‘_
C++11 C++
C++
2.7. 6. C++ 49
Google
C++11 C++11
• <ratio>,
• <cfenv> <fenv.h>
• lambda
2.7.25 acgtyrant
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
. 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 ,
. :
( , ) .
, , . ,
.
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.
; . , , :
2.8.10 7.10.
C/C++ , .
bigopen(): , open()
uint: typedef
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.
. , , ,
, . .
, .
.h , ,
. , ,
.
56 Chapter 2. C++ -
Google
.h .cc , .
2.9.3 8.3.
, , .
,
. , . ,
.
, .
( .h .cc ), ,
, .
2.9.4 8.4.
; .
, .
( , ). ( Opens the file ) ( Open
the file ); , . , .
.
• .
• : , .
2.9. 8. 57
Google
• .
• .
• .
• , ?
, . false ,
:
, , .
, , .
/ , / ,
. ( , )
. , . .
, . ,
, , . ,
.
.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.
, , , .
. :
2.9. 8. 59
Google
. . :
, , .
, :
, :
• , , ,
, .
• , bool enum ,
.
• , ,
. , ,
. , . ,
, , .
• .
• , .
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++ , / :
, .
. :
if (!IsAlreadyProcessed(element)) {
Process(element);
}
2.9.7 8.7. ,
, ; .
. ,
. , , , .
2.9. 8. 61
Google
, . ,
.
, , TODO .
2.9.9 8.9.
DEPRECATED comments .
DEPRECATED , . ,
.
DEPRECATED , , .
, . C++ ,
, .
DEPRECATED , callsites ,
.
, . ,
.
2.9.10 (YuleFox)
2. , ;
3. , , ;
62 Chapter 2. C++ -
Google
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 .
ASCII , UTF-8 .
2.10. 9. 63
Google
, , ASCII .
. , ,
ASCII ; ( ) ASCII . ,
UTF-8 , UTF-8 .
, "\xEF\xBB\xBF",
u8"\uFEFF", Unicode , UTF-8
, .
2.10.3 9.3.
, 2 .
. . .
2.10.4 9.4.
, , ,
.
, :
64 Chapter 2. C++ -
Google
...
}
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;
};
// - , .
void Circle::Rotate(double) {}
, , , :
Lambda ; , .
, & .
int x = 0;
auto add_to_x = [&x](int n) { x += n; };
lambda .
2.10.6 9.6.
66 Chapter 2. C++ -
Google
, , .
, , .
, , ,
if (...) {
...
...
if (...) {
DoSomething(
argument1, argument2, // 4
argument3, argument4);
}
, .
, , . , , ,
, , ,
, , .
.
, ,
// 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 :
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
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 , . ,
.
switch (var) {
case 0: { // 2
... // 4
break;
}
case 1: {
(continues on next page)
70 Chapter 2. C++ -
Google
...
break;
}
default: {
assert(false);
}
}
{} continue, .
while (condition) {
// .
}
for (int i = 0; i < kSomeNumber; ++i) {} // - .
while (condition) continue; // - contunue .
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;
, , , .
2.10.11 9.11.
, .
, (&&) :
, (&&) . Google ,
. , . ,
, && ~, and compl.
2.10.12 9.12.
return .
return result; // , .
// , .
(continues on next page)
72 Chapter 2. C++ -
Google
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 , .
, , .
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.
( , ) :
void SomeFunction();
void SomeFunctionThatDoesNothing() {
}
private:
bool SomeInternalFunction();
74 Chapter 2. C++ -
Google
int some_var_;
int some_other_var_;
};
• 80 .
• ( public) , . .
• .
• .
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
//
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)
...
// , .
vector<char *> x;
2.10.19 9.19.
: , . :
2 , , .
: , . ,
, . .
• .
• if-else .
78 Chapter 2. C++ -
Google
2.10.20 (YuleFox)
1. , , , ;
2. 80 , 22 , ;
5. , , : , ;
6. , / / / ,
, ;
7. ./-> , */& , , ;
8. / , / / / / ;
9. = () , ;
11. / , .
2.10.21 acgtyrant
1. 80 , , .
7. , ,
. , ;
, if (true) true.
2.10. 9. 79
Google
2.11 10.
. , .
2.11.1 10.1.
, . ,
. , .
Windows , :
• ( iNum). Google ,
.cc .
• , , #pragma __declspec.
__declspec(dllimport) __declspec(dllexport) , ,
DLLIMPORT DLLEXPORT, .
, Windows :
• , COM ATL/WTL .
COM ATL/WTL / , .
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 -
2.36
Mike Pinkerton
Greg Miller
Dave MacLachlan
ewangke
Yang.Y
• Google -
3.1.1
ewanke
83
Google
Yang.Y
Objective-C C/C++
• 2.36
3.1.2
Objective-C C
Mac OS X iPhone
Mac OS X
Google
3.1.3
@interface
// Foo.h
// AwesomeProject
//
// Created by Greg Miller on 6/13/08.
// Copyright 2008 Google, Inc. All rights reserved.
//
84 Chapter 3. Objective-C -
Google
#import <Foundation/Foundation.h>
// 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.
//
#import "Foo.h"
@implementation Foo
+ (id)fooWithBar:(NSString *)bar {
return [[[self alloc] initWithBar:bar] autorelease];
}
- (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
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 // aligning keywords instead of colons
error:arg3];
88 Chapter 3. Objective-C -
Google
[myObj short:arg1
longKeyword:arg2
evenLongerKeyword:arg3];
3.2.6
Tip: @ @ {} @catch
Objective-C
@try {
foo();
}
@catch (NSException *ex) {
bar(ex);
}
@finally {
baz();
}
3.2.7
3.2. 89
Google
Tip:
3.2.8
• 4
• 20
• ^{ ^( ) {
// 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
// ...
}
});
// 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];
}
}];
3.3
Objective-C
3.3. 91
Google
/ @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
// file: mac_implementation.mm
#include "cross_platform_header.h"
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:
get
- (id)getDelegate; // AVOID
- (id)delegate; // GOOD
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
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
3.4.2
Tip:
3.4.3
Tip: |
count
96 Chapter 3. Objective-C -
Google
3.4.4
Tip: Objective-C
NSObject retained
weak __weak retained
@property Mac IBOutlets
retained
Objective-C C++
// 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.1 @private
Tip: @private
3.5.2
Tip:
3.5.3
Tip: init
bug
3.5.4 NSObject
3.5.5
98 Chapter 3. Objective-C -
Google
3.5.6 +new
3.5.7 API
C++ Objective-C –
Objective-C
API
// GTMFoo.m
#import "GTMFoo.h"
@implementation GTMFoo(PrivateDelegateHandling)
...
- (NSString *)doSomethingWithDelegate {
// Implement this method
}
...
@end
@implemenation
Objective-C 2.0
@implementation
Bug
Objective-C @implementation
middle truncation
NSString
#import #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
Cocoa Foundation
#import
#include Objective-C
3.5.10 autorelease
Tip: autolease
release
release return
// BETTER
MyController* controller = [[[MyController alloc] init] autorelease];
autorelease retain
autorelease
- (void)setFoo:(GMFoo *)aFoo {
[foo_ autorelease]; // Won't dealloc if |foo_| == |aFoo|
foo_ = [aFoo retain];
}
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
dealloc retained
retain
NSString NSMutableString
- (void)setFoo:(NSString *)aFoo {
[foo_ autorelease];
foo_ = [aFoo copy];
}
3.5.15
-fobjc-exceptions @synchronized
@throw @try @catch @finally
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;
}
3.5.16 nil
Tip: nil
OS X Apple s documentation
3.5.17 BOOL
BOOL _Bool bool C++ Std 4.7.4, 4.12 C99 Std 6.3.1.2
BOOL Boolean Boolean
Objective-C 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
3.5.18 Property
@synthesize
@implementation MyClass
@synthesize name = name_;
@end
@implementation
@interface @implementation
@implementation MyClass
@synthesize name = name_;
- (id)init {
...
}
@end
copy Attribute
3.5.19
Tip:
3.5.20 synthesize
// 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
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 -
4.2
111
Google
Vim Emacs
yapf
4.3 Python
4.3.1 Lint
: , , .
: pylint . , : a) b) c) ,
d) .
: pylint. ,
. :
del . del ,
Unused , :
‘_‘ , unused_,
_. .
4.3.2
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 .
, sound.effects.echo :
. , .
.
typing six.moves .
4.3.3
Tip:
: . .
: , .
: .
yes:
# absl.flags ( ).
import absl.flags
from doctor.who import jodie
FLAGS = absl.flags.FLAGS
# flags ( ).
from absl import flags
from doctor.who import jodie
FLAGS = flags.FLAGS
# .
# 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:
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
(continues on next page)
No:
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.
4. try/except . try , .
, try/except .
5. finally try .
, .
4.3.5
Tip:
: .
: .
: , .
: . , MAX_HOLY_HANDGRENADE_COUNT = 3.
, _ . ,
, _ . . ‘
<>‘_
4.3.6 / /
Tip: .
: , . .
. ( : , ,
nonlocal)
: . .
: (pickled). .
.
: . ,
. , ,
_ , .
4.3.7 &
Tip:
: , & ,
map(), filter(), lambda.( : , ()
)
: . ,
.
: .
: . : , for , . for
. .
Yes:
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))
No:
return ((x, y, z)
for x in xrange(5)
for y in xrange(5)
if x != y
(continues on next page)
for z in xrange(5)
if y != z)
4.3.8
Tip: , . , .
: , , .
. .
: ( , has_key() ). .
: , , , .
. , . .
, dict.iter*() python2 .
Yes:
No:
4.3.9
Tip: .
: , (yield) , ,
. , , .
: , , . ,
.
: .
: . Yields: Returns: .
( : )
4.3.10 Lambda
Tip:
: .
: . . 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 .
if some_long_module.some_long_predicate_function(
really_long_variable_name)
else 'no, false, negative, nay')
4.3.12
Tip: .
: , ( ) .
, . , Python
, .
: . , .
( ), .
: , :
4.3.13 (properties)
(property) .)
Tip: , , . (properties)
.
: . , (attribute) .
: , .
. @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
"""
@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
@property
def perimeter(self):
return self.side * 4
( : , , ?)
4.3.14 True/False
Tip: false
: Python false. ,
false. 0 None, [], {}, false.
: Python . , .
: C/C++ , .
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 not i % 10:
self.handle_multiple_of_ten()
def f(x=None):
x = x or []
5. 0 ( ) true.
4.3.15
: Python .
: Python , .
fn(*args, **kwargs)
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)
)
: bug. PEP-0227 :
i = 4
def foo(x):
def bar():
print i,
# ...
(continues on next page)
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 ).
.
. Main .
API staticmethod .
.
classmethod .
4.3.18
Tip: .
Python , ( :
__hash__ __eq__ Python ) .
( ).
4.3.19
Tip:
: Python , , (metaclasses),
, (on-the-fly compilation), , (object reparenting),
(import hacks), , (modification of system internals), .
: , .
: , . .
( ), ,
.
: .
abc.ABCMeta, collection.
namedtuple, dataclasses , ‘‘enum‘‘ .
: , python3 .
: .
six,future,past
4.3.21
: :
PEP-526 :
a: SomeType = some_func()
python :
: . ,
.
: . . .
: python . API ,
pytype . python ,
( ) . ,
TODO , .
( : IDE vim )
4.4 Python
4.4.1
Tip: , .
4.4.2
Tip: 80
1.
2. URL,
3. url
with .
Python , , . ,
.
, :
URL
with .
with.
; .
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)
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 ( ):
...
}
4.4.5
Tip: ], ), } .
YAPF .
No: golomb4 = [
0,
1,
4,
6
]
4.4.6
Tip: ,
, . , , .
, , .
4.4.7
Tip:
, , , ( ).
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)
, (=), (==, <, >, !=, <>, <=, >=, in, not in, is, is
not), (and, or, not). , .
.
Yes: x == 1
No: x<1
= , . , =
.
, ( :, #, = ):
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
#! Python , , .
#! .
4.4.9
Tip: , ,
Python : . , ,
. __doc__ , pydoc .
( pydoc , ).
( PEP-257 ). : ,
( ). .
, .
.
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.
foo = ClassFoo()
bar = foo.FunctionBar()
"""
, , , .
, :
1.
2.
3.
, . , ,
. , ,
, . ,
. See base class
. ,
.
.
. . , 2 .
Args: , , .
80 , 2 4 (
). . *foo( )
**bar ( ), *foo **bar.
Raises: .
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:
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.
"""
Args: :
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:
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),
(Attributes) . .
class SampleClass(object):
"""Summary of class here.
Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""
def public_method(self):
"""Performs operation blah."""
. ,
. , .
, .
, 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.11
class OuterClass(object):
class InnerClass(object):
pass
class ChildClass(ParentClass):
"""Explicitly inherits from another class already."""
class OuterClass:
class InnerClass:
pass
4.4.12
Tip: , % . ,
+ % .
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)
+ += . ,
, . , ,
.join . ( cStringIO.StringIO .)
, . ,
. , .
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() .
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
, . .
2. , ( ,
).
with :
with , contextlib.closing():
import contextlib
4.4.14 TODO
Tip: TODO , . , .
TODO , ( 2009 11
) ( XML ).
4.4.15
Tip: , typing
Yes: import os
import sys
from typing import Mapping, Sequence
, , .
:
1. __future__
1.
import sys
1.
import tensorflow as tf
1.
, , .
import collections
import queue
import sys
# 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
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
, . .py
, .
1. , , try/except e, with
f.
2. / (-)
3. (Python , __init__)
1. (Internal) , , .
3. (__) .
4. . Java, .
5. ( CapWords, Pascal ),
( lower_with_under.py). CapWords.py
, , , .
python .py -.
, exec "$0.py" "$@" bash .
Python Guido
4.4.19 Main
Tip: , .
(main functionality) , . main() .
Python , pydoc . if
__name__ == '__main__' , .
absl, app.run :
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
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:
...
. , ,
.
, , , 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 ) ( , .
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 , = .
Yes:
def func(a: int = 0) -> int:
...
No:
def func(a:int=0) -> int:
...
NoneType
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]]]
# pytype: disable=attribute-error
, :
# type::
, :
a: Foo = SomeUndecoratedFunction()
Tuples vs Lists
Lists . Tuples
, . ( :
, python ,list tuple , ,
list tuple )
TypeVars
python . TypeVars.
TypeVar
python . python3
, str. Text . , .
python2 , Text. , str . unicode,
No:
def py2_code(x: str) -> unicode:
...
, bytes.
, Union ,
.
, ,
AnyStr. python3
typing , . typing
, :
, typing
, . ,
‘‘import x as y‘‘ :
, ,
. , .
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,
). .
, . , Any .
Any , . , TypeVar
.
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
Shell -
Contents
• Shell -
5.1
1.26
Paul Armstrong
• Google -
5.2
5.2.1 Shell
153
Google
Solaris SVR4
Bourne shell
5.2.2 Shell
Tip: Shell
Shell
• shell
• shell
• ${PHPESTATUS} Python
5.3 Shell
5.3.1
shell
.sh
sudo
5.4
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
Tip:
5.5.4 TODO
Tip: TODO
C++
5.6
5.6.1
Tip:
5.6.2
Tip: 80
80 here document
80
5.6. 157
Google
END
5.6.3
Tip:
2 | || &&
# Long commands
command1 \
| command2 \
| command3 \
| command4
5.6.4
shell ; do , ; then
if/for/while else
else
mkdir -p "${ dir}/${ ORACLE_SID}"
if [[ "$?" -ne 0 ]]; then
error_message
fi
fi
done
5.6.5 case
Tip:
• 2
• ;;
• ;;
case esac
;& ;;&
;;
;;
;;
verbose='false'
aflag=''
bflag=''
files=''
(continues on next page)
5.6. 159
Google
5.6.6
1.
2.
3. shell
# Braces necessary:
echo "many parameters: ${ 10}"
5.6.7
Tip:
• shell
• [[
• $@ $*
# Simple examples
# "quote command substitutions"
flag="$(some_command and its args "$@" 'quoted separately')"
# "quote variables"
echo "${ flag}"
5.6. 161
Google
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
Tip: $(command)
$(command)
# This is preferred:
var="$(command "$(command1)")"
# This is not:
var="`command \`command1\``"
5.7.2 test [ [[
[[ ]] [[ ... ]]
[[ ... ]] [ ... ]
# This matches the exact pattern "f*" (Does not match in this case)
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
# Not this:
if [[ "${ my_var}X" = "some_stringX" ]]; then
do_something
fi
‘-z‘ ‘-n‘
# Use this
if [[ -n "${ my_var}" ]]; then
do_something
fi
5.7.4
Tip:
- ./* *
# 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
5.7.6 while
5.7. 165
Google
last_line='NULL'
your_command | while read line; do
last_line="${ line}"
done
for
total=0
# Only do this if there are no spaces in return values.
for value in $(command); do
total+="${ value}"
done
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
5.8
5.8.1
Tip: ::
function
# Single function
my_func() {
...
}
# Part of a package
mypackage::my_func() {
...
}
() function
5.8.2
Tip:
5.8.3
Tip:
5.8. 167
Google
# Constant
readonly PATH_TO_FILES='/some/path'
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:
5.8.5
shell
5.8.6
Tip: local
local
local
my_func2() {
local name="$1"
...
}
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
# 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
PIPESTATUS
PIPESTATUS [ PIPESTATUS
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
Javascript -
6.1
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
@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
// 1.
MyClass.prototype.myMethod = function() {
return 42;
} // .
(function() {
//
})();
var x = {
'i': 1,
'j': 2
} // .
// 2. IE firefox .
// .
[normalVersion, ffVersion][isIE]();
// 3.
-1 == resultOfOperation() || die();
1. js 42
42
js
) } ]
( { [ js
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
hack
6.2.8
string.charAt(3)
string[3] DOM
6.2.9
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 );
D.prototype.method =function() {
...
};
6.2.11
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)
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.15 with() {}
with with
with (foo) {
var x = 3;
return x;
}
x foo setter
3 with
6.2.16 this
this
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]); //
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
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);
// 0
var a4 = new Array();
var o = {};
var o2 = {
a: 0,
b: 1,
c: 2,
'strange key': 3
};
6.2.21
Object.prototype Array.prototype
Function.prototype
var f = function () {
/*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/
};
JavaScript
6.3 Javascript
6.3.1
opt_
var_args var_args
arguments
@param
getter setter
/**
* -- .
*/
var foo = { get next() { return this.nextId++; } };
};
JavaScript
JavaScript
Project
Sloth sloth.*
sloth.sleep = function() {
...
};
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)
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
myapp.main = function() {
var namespace = some.long.namespace;
namespace.MyClass.staticHelper(new namespace.MyClass());
};
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.3
6.3.4
window
window window
6.3.5
C++
if (something) {
// ...
} else {
//
}
//
var inset = {
top: 10,
right: 20,
bottom: 15,
left: 12
};
//
(continues on next 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)
// ...
};
//
//
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)));
}
function
goog.scope
goog.scope
C++ goog.scope 0
goog.scope(function() {
var Button = goog.ui.Button;
goog.provide('my.module');
goog.require('goog.dom');
goog.require('goog.ui.Button');
goog.scope(function() {
(continues on next page)
4 2
someWonderfulHtml = '' +
getEvenMoreHtml(someReallyInterestingValues, moreValues,
evenMoreParams, 'a duck', true, 72,
slightlyMoreMonkeys(0xfff)) +
'';
thisIsAVeryLongVariableName =
hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();
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();
}
doSomethingTo(x);
doSomethingElseTo(x);
andThen(x);
nowDoSomethingWith(y);
andNowWith(z);
// Indentation +4 is OK.
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;
var x = foo.bar().
doSomething().
doSomethingElse();
6.3.6
6.3.7
' "
6.3.8
--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
// File 1.
/** @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);
/**
* @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 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 }
length Array.
<{length}>
{function(string,
boolean)}
{function(): number}
{function(this:goog.ui.
6.3. Javascript 197
this Menu, string)}
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
Javascript
/**
*
* @param {Object} value
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {Object}
* @private
*/
this.myValue_ = value;
}
/**
* null
* @param {!Object} value
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {!Object}
* @private
*/
this.myValue_ = value;
}
MyClass null
undefined
/**
*
* @param {Object=} opt_value
* @constructor
*/
function MyClass(opt_value) {
/**
* Some value.
* @type {Object|undefined}
* @private
*/
this.myValue_ = opt_value;
}
/**
*
* @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
/**
* @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
//
/**
* 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
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)
/**
* 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
/**
* @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() {
//
};
/**
* 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() {
...
}
/**
* 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) {
// ...
};
/**
* Enum for tri-state␣
,→ values.
* @enum {number}
*/
project.TriState = {
TRUE: 1,
FALSE: -1,
MAYBE: 0
};
@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
@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)
*/
/**
• 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()
,→ {
// ...
};
@interface @interface
/**
* A shape.
* @interface
*/
function Shape() {};
Shape.prototype.draw =␣
,→function() {};
/**
* A polygon.
* @interface
* @extends {Shape}
*/
function Polygon() {};
Polygon.prototype.
,→getSides =␣
,→function() {};
goog.object.extend(
Button.prototype, @type {Foo} Foo
/** @lends {Button. @lends {Foo} Foo
,→prototype} */ { .
isButton:␣ JSDoc Toolkit docs
,→function() { return␣
,→true; }
});
@noalias @noalias
/** @noalias */
function Range() {}
@nosideeffects @nosideeffects
/** @nosideeffects */
function␣
,→noSideEffectsFn1() {
// ...
};
/** @nosideeffects */
var noSideEffectsFn2 =␣
,→function() {
// ...
};
/** @nosideeffects */
a.prototype.
,→noSideEffectsFn3 =␣
,→function() {
// ...
};
@override @override
/**
* @return {string}␣
,→ Human-readable␣
,→ representation of␣
,→ project.SubClass.
* @override
*/
project.SubClass.
,→ prototype.toString()
,→ {
// ...
};
/**
* 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) {
// ...
};
/**
* Adds a single item,␣
,→recklessly.
* @see #addSafely
* @see goog.Collect
* @see goog.
,→RecklessAdder#add
...
Foo.prototype = /**␣
,→ @struct */ {
method1: function()
,→ {}
};
Foo.prototype.method2␣
,→ = function() {}; //␣
,→ warning
/**
* @fileoverview Event␣
,→ Manager
* Provides an␣
,→ abstracted interface␣
,→ to the
* browsers' event␣
,→ systems.
* @supported So far␣
,→ tested in IE6 and␣
,→ FF1.5
*/
/**
* @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) {
...
};
/**
• 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) {
...
}
• @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
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
• []
• {}
while (x != null) {
x 0 false
while (x) {
null
if (y) {
• 0 != null 0 == [] 0 == false
if (val != 0) {
return foo();
} else {
return bar();
}
HTML
&& ||
|| default
&&
if (node) {
if (node.kids) {
if (node.kids[index]) {
foo(node.kids[index]);
}
}
}
length
O(n) length O(n^2)
( false )
firstChild nextSibling
TypeScript
7.1
7.1.1
RFC 2119
7.1.2
2021 09 02
• TinkerRobot
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
_ _
lowerCamelCase snake_case
• 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
class Teapot {
readonly BrewStateEnum = BrewStateEnum;
readonly CAPACITY = CAPACITY;
}
TypeScript
Testing Blog
• _
• opt_
– 1.5. #include
• IMyInterface
MyFooInterface
TodoItem JSON
TodoItemStorage
• Observable $
API
i j
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
• /** JSDoc */
• //
JSDoc
JSDoc
/** JSDoc */
/** JSDoc */
TypeScript
7.2. 231
Google
@override
//
/** @param fooBarService Foo Bar */
@param @return
/**
* POST
* @param amountLitres
*/
brew(amountLitres: number, logger: Logger) {
// ...
}
class Foo {
constructor(private readonly bar: Bar) { }
}
JSDoc @param
/** */
class ParamProps {
/**
* @param percolator
* @param beans
*/
constructor(
(continues on next page)
/** */
class OrdinaryClass {
/** brew() */
nextBean: CoffeeBean;
constructor(initialBean: CoffeeBean) {
this.nextBean = initialBean;
}
}
/* */
//
new Percolator().brew(/* amountLitres= */ 5);
// brew
new Percolator().brew({amountLitres: 5});
JSDoc
7.2. 233
Google
JSDoc
/** "bar" */
@Component({
selector: 'foo',
template: 'bar',
})
export class FooComponent {}
7.3
7.3.1
class Foo {
public bar = new Bar(); // public
class Foo {
bar = new Bar(); // public
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
private constructor() {}
}
7.3.3
#private
#private
//
class Clazz {
#ident = 1;
}
TypeScript
//
class Clazz {
private ident = 1;
}
readonly
readonly
TypeScript
//
class Foo {
private readonly barService: BarService;
constructor(barService: BarService) {
this.barService = barService;
}
}
//
class Foo {
constructor(private readonly barService: BarService) {}
}
JSDoc @param
//
class Foo {
private readonly userList: string[];
constructor() {
this.userList = [];
}
}
//
class Foo {
private readonly userList: string[] = [];
}
TypeScript obj['foo']
private
obj['foo'] TypeScript
7.3. 237
Google
class Foo {
constructor(private readonly someService: SomeService) {}
internal wrapped
public
readonly
class Foo {
private wrappedBar = '';
get bar() {
return this.wrappedBar || 'bar';
}
class Bar {
private barInternal = '';
// bar public
get bar() {
return this.barInternal;
}
7.3.4
//
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
//
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
7.3. 239
Google
string
Number()
NaN
+
+
//
const x = +y;
parseInt parseFloat
12 dwarves 12
parseInt
let f = Number(someString);
if (isNaN(f)) handleError();
f = Math.floor(f);
//
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
//
var foo = someValue;
7.3.8
//
throw new Error('Foo is not a valid bar.');
(continues on next page)
7.3. 241
Google
//
throw Error('Foo is not a valid bar.');
7.3.9
//
for (const x in someObj) {
// x someObj
}
//
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 (const x in someArray) {
(continues on next page)
// x ( string )
}
//
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()) {
//
}
//
someArr.forEach((item, index) => {
someFn(item, index);
});
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
//
const foo = shouldUseFoo ? {num: 7} : {};
const bar = {num: 5, ...foo};
//
const fooStrings = ['a', 'b', 'c'];
const ids = [...fooStrings, 'd', 'e'];
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
// ...
}
//
switch (x) {
case X:
case Y:
doSomething();
break;
default: //
}
7.3.14
=== !==
JavaScript JavaScript
//
if (foo == 'bar' || baz != bam) {
//
}
//
if (foo === 'bar' || baz !== bam) {
//
}
//
if (foo == null) {
// foo null undefined
}
7.3.15
this
//
function foo() { ... }
//
//
foo = () => 3; //
//
const foo = function() { ... }
function foo() {}
doSomethingWith(function() {});
interface SearchFunction {
(source: string, subString: string): boolean;
}
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));
// { ... }
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)
// 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
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
}
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)
}
}
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
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,
};
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
7.3.22 debugger
debugger
//
function debugMe() {
debugger;
}
7.3.23
@ @MyDecorator
• 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
TypeScript ES6
import {foo} from 'bar'
//
namespace Rocket {
function launch() { ... }
}
// <reference>
/// <reference path="..."/>
// require()
import x = require('mydep');
7.4.2
//
export default class Foo { ... }
//
import Foo from './bar'; //
import Bar from './bar'; //
foo.ts
//
const foo = 'blah';
export default foo;
bar.ts
//
import {fizz} from './foo';
// fizz
import fizz from './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)
//
export const FOO = 1;
export function bar() { return 1; }
7.4.3
ES6 TypeScript
//
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 = ...;
//
//
//
testing.describe('foo', () => {
testing.it('bar', () => {
testing.expect(...);
testing.expect(...);
});
});
//
import {describe, it, expect} from './testing';
describe('foo', () => {
it('bar', () => {
expect(...);
expect(...);
});
});
...
1.
2.
3. RxJS from
observableFrom
//
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 '...'
7.4.4
7.5
7.5.1
TypeScript
google3
any
const x = 15; // x .
7.5. 261
Google
// boolean
const x: boolean = true;
// Set
const x: Set<string> = new Set();
// TypeScript
const x = new Set<string>();
TypeScript
|null |undefined
|null |undefined
// undefined
type CoffeeResponse = Latte|Americano|undefined;
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;
}
|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;
}
/**
* 'cat' '{sound: string}'
*/
const cat = {
sound: 'meow',
};
/**
(continues on next page)
* 'cat'
* TypeScript
* 'cat'
*/
makeSound(cat);
/**
* Horse
* 'horse' 'Animal'
*/
const horse: Animal = {
sound: 'niegh',
};
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>
//
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)[];
JavaScript
TypeScript
//
const users: {[key: string]: number} = ...;
//
const users: {[userName: string]: number} = ...;
7.5.7
TypeScript Type-
Script Record Partial Readonly
TypeScript
• TypeScript
• /
• IDE
Pick<T, Keys>
interface User {
shoeSize: number;
favoriteIcecream: string;
favoriteChocolate: string;
}
FoodPreferences
interface FoodPreferences {
favoriteIcecream: string;
(continues on next page)
7.5. 267
Google
favoriteChocolate: string;
}
interface 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)
// 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
// 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): [string, string] {
// ...
return [x, y];
}
// :
const [leftHalf, rightHalf] = splitInHalf('my string');
// :
const address = splitHostPort(userAddress);
use(address.port);
//
const {host, port} = splitHostPort(userAddress);
7.5.10
JavaScript
7.5.11
API API
7.6
7.6.1
1.
• any
• TypeScript
• .
• private
2.
JavaScript
• x as T <T>x
3.
7.6. 271
Google
TypeScript
• Clousure TS
• google3
4.
Bug