Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
a5d6f834
Commit
a5d6f834
authored
Sep 14, 2009
by
Rob Pike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
functions
R=rsc DELTA=125 (103 added, 22 deleted, 0 changed) OCL=34586 CL=34598
parent
8a0cb930
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
97 additions
and
16 deletions
+97
-16
doc/effective_go.html
doc/effective_go.html
+97
-16
No files found.
doc/effective_go.html
View file @
a5d6f834
...
...
@@ -618,32 +618,113 @@ func Compare(a, b []byte) int {
}
</pre>
<h2>
More to come
</h2>
<!---
<h2
id=
"functions"
>
Functions
</h2>
<h3 id="omit-wrappers">Omit needless wrappers</h3>
<h3
id=
"multiple-returns"
>
Multiple return values
</h3>
<p>
One of Go's unusual properties is that functions and methods
can return multiple values. This feature can be used to
improve on a couple of clumsy idioms in C program: in-band
error returns (
<code>
-1
</code>
for
<code>
EOF
</code>
for example)
and modifying an argument.
</p>
<p>
In C, a write error is signaled by a negative byte count with the
error code secreted away in a volatile location.
In Go,
<code>
Write
</code>
can return a byte count
<i>
and
</i>
an error: "Yes, you wrote some
bytes but not all of them because you filled the device".
The signature of
<code>
*File.Write
</code>
in package
<code>
os
</code>
is:
</p>
<pre>
func (file *File) Write(b []byte) (n int, err Error)
</pre>
<p>
and as the documentation says, it returns the number of bytes
written and a non-nil
<code>
Error
</code>
when
<code>
n
</code>
<code>
!=
</code>
<code>
len(b)
</code>
.
This is a common style; see the section on error handling for more examples.
</p>
<p>
A similar approach obviates the need to pass a pointer to a return
value to overwrite an argument. Here's a simple-minded function to
grab a number from a position in a byte array, returning the number
and the next position.
</p>
<pre>
func nextInt(b []byte, i int) (int, int) {
for ; i
<
len
(
b
)
&
amp
;&
amp
;
!
isDigit
(
b
[
i
]);
i
++
{
}
x
:=
0;
for
;
i
<
len
(
b
)
&
amp
;&
amp
;
isDigit
(
b
[
i
]);
i
++
{
x =
x*10
+
int
(
b
[
i
])
-
'
0
'
}
return
x
,
i
;
}
</
pre
>
<p>
You could use it to scan the numbers in an input array
<code>
a
</code>
like this:
</p>
<pre>
for i := 0; i
<
len
(
a
);
{
x
,
i =
nextInt(a,
i
);
fmt
.
Println
(
x
);
}
</
pre
>
<h3
id=
"named-results"
>
Named result parameters
</h3>
<p>
Functions are great for factoring out common code, but
if a function is only called once,
ask whether it is necessary,
especially if it is just a short wrapper around another function.
This style is rampant in C++ code: wrappers
call wrappers that call wrappers that call wrappers.
This style hinders people trying to understand the program,
not to mention computers trying to execute it.
The return or result "parameters" of a Go function can be given names and
used as regular variables, just like the incoming parameters.
When named, they are initialized to the zero for their type when
the function begins; if the function executes a
<code>
return
</code>
statement
with no arguments, the current values of the result parameters are
used as the returned values.
</p>
<h3 id="multiple-returns">Return multiple values</h3>
<p>
The names are not mandatory but they can make code shorter and clearer:
they're documentation.
If we name the results of
<code>
nextInt
</code>
it becomes
obvious which returned
<code>
int
</code>
is which.
</p>
<pre>
func nextInt(b []byte, pos int) (value, nextPos int) {
</pre>
<p>
If a function must return multiple values, it can
do so directly.
There is no need to pass a pointer to a return value.
Because named results are initialized and tied to an unadorned return, they can simplify
as well as clarify. Here's a version
of
<code>
io.ReadFull
</code>
that uses them well:
</p>
<pre>
func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
for len(buf) > 0
&&
err != nil {
var nr int;
nr, err = r.Read(buf);
n += nr;
buf = buf[nr:len(buf)];
}
return;
}
</pre>
<h2>
More to come
</h2>
<!---
<h2 id="idioms">Idioms</h2>
<h3 id="struct-allocation">Allocate using literals</h3>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment