1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-08-06 23:06:49 +02:00

Merge branch 'master' of github.com:adambard/learnxinyminutes-docs

This commit is contained in:
Camilo Garrido
2013-08-11 12:47:21 -04:00
8 changed files with 785 additions and 98 deletions

View File

@@ -16,8 +16,9 @@ properly!
The most requested languages are: The most requested languages are:
* Scala * Go
* Javascript * ~~Scala~~
* ~~Javascript~~
... but there are many more requests to do "every language", so don't let that stop you. ... but there are many more requests to do "every language", so don't let that stop you.

View File

@@ -310,7 +310,12 @@ Pulls from a repository and merges it with another branch.
# Update your local repo, by merging in new changes # Update your local repo, by merging in new changes
# from the remote "origin" and "master" branch. # from the remote "origin" and "master" branch.
# git pull <remote> <branch> # git pull <remote> <branch>
# git pull => implicitly defaults to => git pull origin master
$ git pull origin master $ git pull origin master
# Merge in changes from remote branch and rebase
# branch commits onto your local repo, like: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase
``` ```
### push ### push

View File

@@ -131,7 +131,7 @@ add 1 2 -- 3
-- with backticks: -- with backticks:
1 `add` 2 -- 3 1 `add` 2 -- 3
-- You can also define functions that have no characters! This lets -- You can also define functions that have no letters! This lets
-- you define your own operators! Here's an operator that does -- you define your own operators! Here's an operator that does
-- integer division -- integer division
(//) a b = a `div` b (//) a b = a `div` b

View File

@@ -6,7 +6,7 @@ filename: learnpython.py
--- ---
Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular
languages in existence. I fell in love with Python for its syntactic clarity. Its basically languages in existence. I fell in love with Python for its syntactic clarity. It's basically
executable pseudocode. executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service] Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]

View File

@@ -5,7 +5,7 @@ contributors:
filename: learnr.r filename: learnr.r
--- ---
R is a statistical computing language. It has lots of good built-in functions for uploading and cleaning data sets, running common statistical tests, and making graphs. You can also easily compile it within a LaTeX document. R is a statistical computing language. It has lots of libraries for uploading and cleaning data sets, running statistical procedures, and making graphs. You can also run `R`commands within a LaTeX document.
```python ```python
@@ -14,63 +14,244 @@ R is a statistical computing language. It has lots of good built-in functions fo
# You can't make a multi-line comment per se, # You can't make a multi-line comment per se,
# but you can stack multiple comments like so. # but you can stack multiple comments like so.
# Hit COMMAND-ENTER to execute a line # in Windows, hit COMMAND-ENTER to execute a line
###################################################################
# Stuff you can do without understanding anything about programming
###################################################################
data() # Browse pre-loaded data sets
data(rivers) # Lengths of Major North American Rivers
ls() # Notice that "rivers" appears in the workspace
head(rivers) # peek at the dataset
# 735 320 325 392 524 450
length(rivers) # how many rivers were measured?
# 141
summary(rivers)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 135.0 310.0 425.0 591.2 680.0 3710.0
stem(rivers) #stem-and-leaf plot (like a histogram)
#
# The decimal point is 2 digit(s) to the right of the |
#
# 0 | 4
# 2 | 011223334555566667778888899900001111223333344455555666688888999
# 4 | 111222333445566779001233344567
# 6 | 000112233578012234468
# 8 | 045790018
# 10 | 04507
# 12 | 1471
# 14 | 56
# 16 | 7
# 18 | 9
# 20 |
# 22 | 25
# 24 | 3
# 26 |
# 28 |
# 30 |
# 32 |
# 34 |
# 36 | 1
stem(log(rivers)) #Notice that the data are neither normal nor log-normal! Take that, Bell Curve fundamentalists.
# The decimal point is 1 digit(s) to the left of the |
#
# 48 | 1
# 50 |
# 52 | 15578
# 54 | 44571222466689
# 56 | 023334677000124455789
# 58 | 00122366666999933445777
# 60 | 122445567800133459
# 62 | 112666799035
# 64 | 00011334581257889
# 66 | 003683579
# 68 | 0019156
# 70 | 079357
# 72 | 89
# 74 | 84
# 76 | 56
# 78 | 4
# 80 |
# 82 | 2
hist(rivers, col="#333333", border="white", breaks=25) #play around with these parameters
hist(log(rivers), col="#333333", border="white", breaks=25) #you'll do more plotting later
#Here's another neat data set that comes pre-loaded. R has tons of these. data()
data(discoveries)
plot(discoveries, col="#333333", lwd=3, xlab="Year", main="Number of important discoveries per year")
plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", main="Number of important discoveries per year")
#rather than leaving the default ordering (by year) we could also sort to see what's typical
sort(discoveries)
# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
stem(discoveries, scale=2)
#
# The decimal point is at the |
#
# 0 | 000000000
# 1 | 000000000000
# 2 | 00000000000000000000000000
# 3 | 00000000000000000000
# 4 | 000000000000
# 5 | 0000000
# 6 | 000000
# 7 | 0000
# 8 | 0
# 9 | 0
# 10 | 0
# 11 |
# 12 | 0
max(discoveries)
# 12
summary(discoveries)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 0.0 2.0 3.0 3.1 4.0 12.0
#Basic statistical operations don't require any programming knowledge either
#roll a die a few times
round(runif(7, min=.5, max=6.5))
# 1 4 6 1 4 6 4
#your numbers will differ from mine unless we set the same random.seed(31337)
#draw from a standard Gaussian 9 times
rnorm(9)
# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
# [7] -0.59975593 0.57629164 1.08455362
######################### #########################
# The absolute basics # Basic programming stuff
######################### #########################
# NUMBERS # NUMBERS
# We've got doubles! Behold the "numeric" class # "numeric" means double-precision floating-point numbers
5 # => [1] 5 5 # 5
class(5) # => [1] "numeric" class(5) # "numeric"
# We've also got integers! They look suspiciously similar, 5e4 # 50000 #handy when dealing with large,small,or variable orders of magnitude
# but indeed are different 6.02e23 # Avogadro's number
5L # => [1] 5 1.6e-35 # Planck length
class(5L) # => [1] "integer"
# long-storage integers are written with L
5L # 5
class(5L) # "integer"
# Try ?class for more information on the class() function # Try ?class for more information on the class() function
# In fact, you can look up the documentation on just about anything with ? # In fact, you can look up the documentation on `xyz` with ?xyz
# or see the source for `xyz` by evaluating xyz
# Arithmetic
10 + 66 # 76
53.2 - 4 # 49.2
2 * 2.0 # 4
3L / 4 # 0.75
3 %% 2 # 1
# Weird number types
class(NaN) # "numeric"
class(Inf) # "numeric"
class(-Inf) # "numeric" #used in for example integrate( dnorm(x), 3, Inf ) -- which obviates Z-score tables
# but beware, NaN isn't the only weird type...
class(NA) # see below
class(NULL) # NULL
# SIMPLE LISTS
c(6, 8, 7, 5, 3, 0, 9) # 6 8 7 5 3 0 9
c('alef', 'bet', 'gimmel', 'dalet', 'he') # "alef" "bet" "gimmel" "dalet" "he"
c('Z', 'o', 'r', 'o') == "Zoro" # FALSE FALSE FALSE FALSE
#some more nice built-ins
5:15 # 5 6 7 8 9 10 11 12 13 14 15
seq(from=0, to=31337, by=1337)
# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
letters
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
# [20] "t" "u" "v" "w" "x" "y" "z"
month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# Access the n'th element of a list with list.name[n] or sometimes list.name[[n]]
letters[18] # "r"
LETTERS[13] # "M"
month.name[9] # "September"
c(6, 8, 7, 5, 3, 0, 9)[3] # 7
# All the normal operations!
10 + 66 # => [1] 76
53.2 - 4 # => [1] 49.2
2 * 2.0 # => [1] 4
3L / 4 # => [1] 0.75
3 %% 2 # => [1] 1
# Finally, we've got not-a-numbers! They're numerics too
class(NaN) # => [1] "numeric"
# CHARACTERS # CHARACTERS
# We've (sort of) got strings! Behold the "character" class
"plugh" # => [1] "plugh"
class("plugh") # "character"
# There's no difference between strings and characters in R # There's no difference between strings and characters in R
"Horatio" # "Horatio"
class("Horatio") # "character"
substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
# LOGICALS # LOGICALS
# We've got booleans! Behold the "logical" class # booleans
class(TRUE) # => [1] "logical" class(TRUE) # "logical"
class(FALSE) # => [1] "logical" class(FALSE) # "logical"
# Behavior is normal # Behavior is normal
TRUE == TRUE # => [1] TRUE TRUE == TRUE # TRUE
TRUE == FALSE # => [1] FALSE TRUE == FALSE # FALSE
FALSE != FALSE # => [1] FALSE FALSE != FALSE # FALSE
FALSE != TRUE # => [1] TRUE FALSE != TRUE # TRUE
# Missing data (NA) is logical, too # Missing data (NA) is logical, too
class(NA) # => [1] "logical" class(NA) # "logical"
# FACTORS # FACTORS
# The factor class is for categorical data # The factor class is for categorical data
# It has an attribute called levels that describes all the possible categories # which can be ordered (like childrens' grade levels)
factor("dog") # or unordered (like gender)
# => levels(factor(c("female", "male", "male", "female", "NA", "female"))) # "female" "male" "NA"
# [1] dog
# Levels: dog factor(c("female", "female", "male", "NA", "female"))
# (This will make more sense once we start talking about vectors) # female female male NA female
# Levels: female male NA
data(infert) #Infertility after Spontaneous and Induced Abortion
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
# VARIABLES # VARIABLES
@@ -80,8 +261,8 @@ y <- "1" # this is preferred
TRUE -> z # this works but is weird TRUE -> z # this works but is weird
# We can use coerce variables to different classes # We can use coerce variables to different classes
as.numeric(y) # => [1] 1 as.numeric(y) # 1
as.character(x) # => [1] "5" as.character(x) # "5"
# LOOPS # LOOPS
@@ -122,7 +303,7 @@ myFunc <- function(x) {
} }
# Called like any other R function: # Called like any other R function:
myFunc(5) # => [1] 19 myFunc(5) # 19
######################### #########################
# Fun with data: vectors, matrices, data frames, and arrays # Fun with data: vectors, matrices, data frames, and arrays
@@ -132,35 +313,35 @@ myFunc(5) # => [1] 19
# You can vectorize anything, so long as all components have the same type # You can vectorize anything, so long as all components have the same type
vec <- c(8, 9, 10, 11) vec <- c(8, 9, 10, 11)
vec # => [1] 8 9 10 11 vec # 8 9 10 11
# The class of a vector is the class of its components # The class of a vector is the class of its components
class(vec) # => [1] "numeric" class(vec) # "numeric"
# If you vectorize items of different classes, weird coercions happen # If you vectorize items of different classes, weird coercions happen
c(TRUE, 4) # => [1] 1 4 c(TRUE, 4) # 1 4
c("dog", TRUE, 4) # => [1] "dog" "TRUE" "4" c("dog", TRUE, 4) # "dog" "TRUE" "4"
# We ask for specific components like so (R starts counting from 1) # We ask for specific components like so (R starts counting from 1)
vec[1] # => [1] 8 vec[1] # 8
# We can also search for the indices of specific components, # We can also search for the indices of specific components,
which(vec %% 2 == 0) # => [1] 1 3 which(vec %% 2 == 0) # 1 3
# or grab just the first or last entry in the vector # or grab just the first or last entry in the vector
head(vec, 1) # => [1] 8 head(vec, 1) # 8
tail(vec, 1) # => [1] 11 tail(vec, 1) # 11
# If an index "goes over" you'll get NA: # If an index "goes over" you'll get NA:
vec[6] # => [1] NA vec[6] # NA
# You can find the length of your vector with length() # You can find the length of your vector with length()
length(vec) # => [1] 4 length(vec) # 4
# You can perform operations on entire vectors or subsets of vectors # You can perform operations on entire vectors or subsets of vectors
vec * 4 # => [1] 16 20 24 28 vec * 4 # 16 20 24 28
vec[2:3] * 5 # => [1] 25 30 vec[2:3] * 5 # 25 30
# and there are many built-in functions to summarize vectors # and there are many built-in functions to summarize vectors
mean(vec) # => [1] 9.5 mean(vec) # 9.5
var(vec) # => [1] 1.666667 var(vec) # 1.666667
sd(vec) # => [1] 1.290994 sd(vec) # 1.290994
max(vec) # => [1] 11 max(vec) # 11
min(vec) # => [1] 8 min(vec) # 8
sum(vec) # => [1] 38 sum(vec) # 38
# TWO-DIMENSIONAL (ALL ONE CLASS) # TWO-DIMENSIONAL (ALL ONE CLASS)
@@ -175,11 +356,11 @@ mat
# Unlike a vector, the class of a matrix is "matrix", no matter what's in it # Unlike a vector, the class of a matrix is "matrix", no matter what's in it
class(mat) # => "matrix" class(mat) # => "matrix"
# Ask for the first row # Ask for the first row
mat[1,] # => [1] 1 4 mat[1,] # 1 4
# Perform operation on the first column # Perform operation on the first column
3 * mat[,1] # => [1] 3 6 9 3 * mat[,1] # 3 6 9
# Ask for a specific cell # Ask for a specific cell
mat[3,2] # => [1] 6 mat[3,2] # 6
# Transpose the whole matrix # Transpose the whole matrix
t(mat) t(mat)
# => # =>
@@ -196,7 +377,7 @@ mat2
# [2,] "2" "cat" # [2,] "2" "cat"
# [3,] "3" "bird" # [3,] "3" "bird"
# [4,] "4" "dog" # [4,] "4" "dog"
class(mat2) # => [1] matrix class(mat2) # matrix
# Again, note what happened! # Again, note what happened!
# Because matrices must contain entries all of the same class, # Because matrices must contain entries all of the same class,
# everything got converted to the character class # everything got converted to the character class
@@ -216,7 +397,7 @@ mat3
# For columns of different classes, use the data frame # For columns of different classes, use the data frame
dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog")) dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog"))
names(dat) <- c("number", "species") # name the columns names(dat) <- c("number", "species") # name the columns
class(dat) # => [1] "data.frame" class(dat) # "data.frame"
dat dat
# => # =>
# number species # number species
@@ -224,14 +405,14 @@ dat
# 2 2 cat # 2 2 cat
# 3 1 bird # 3 1 bird
# 4 4 dog # 4 4 dog
class(dat$number) # => [1] "numeric" class(dat$number) # "numeric"
class(dat[,2]) # => [1] "factor" class(dat[,2]) # "factor"
# The data.frame() function converts character vectors to factor vectors # The data.frame() function converts character vectors to factor vectors
# There are many twisty ways to subset data frames, all subtly unalike # There are many twisty ways to subset data frames, all subtly unalike
dat$number # => [1] 5 2 1 4 dat$number # 5 2 1 4
dat[,1] # => [1] 5 2 1 4 dat[,1] # 5 2 1 4
dat[,"number"] # => [1] 5 2 1 4 dat[,"number"] # 5 2 1 4
# MULTI-DIMENSIONAL (ALL OF ONE CLASS) # MULTI-DIMENSIONAL (ALL OF ONE CLASS)

View File

@@ -275,36 +275,36 @@ surround { puts 'hello world' }
# Define a class with the class keyword # Define a class with the class keyword
class Human class Human
# A class variable. It is shared by all instances of this class. # A class variable. It is shared by all instances of this class.
@@species = "H. sapiens" @@species = "H. sapiens"
# Basic initializer # Basic initializer
def initialize(name, age=0) def initialize(name, age=0)
# Assign the argument to the "name" instance variable for the instance # Assign the argument to the "name" instance variable for the instance
@name = name @name = name
# If no age given, we will fall back to the default in the arguments list. # If no age given, we will fall back to the default in the arguments list.
@age = age @age = age
end end
# Basic setter method # Basic setter method
def name=(name) def name=(name)
@name = name @name = name
end end
# Basic getter method # Basic getter method
def name def name
@name @name
end end
# A class method uses self to distinguish from instance methods. # A class method uses self to distinguish from instance methods.
# It can only be called on the class, not an instance. # It can only be called on the class, not an instance.
def self.say(msg) def self.say(msg)
puts "#{msg}" puts "#{msg}"
end end
def species def species
@@species @@species
end end
end end

View File

@@ -408,9 +408,11 @@ for(line <- Source.fromPath("myfile.txt").getLines())
[Scala for the impatient](http://horstmann.com/scala/) [Scala for the impatient](http://horstmann.com/scala/)
[Twitter Scala school(http://twitter.github.io/scala_school/) [Twitter Scala school](http://twitter.github.io/scala_school/)
[The scala documentation] [The scala documentation](http://docs.scala-lang.org/)
[Try Scala in your browser](http://scalatutorials.com/tour/)
Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user) Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)

498
zh-cn/dart-cn.html.markdown Normal file
View File

@@ -0,0 +1,498 @@
---
language: dart
filename: learndart.dart
contributors:
- ["Joao Pedrosa", "https://github.com/jpedrosa/"]
translators:
- ["Guokai Han", "https://github.com/hanguokai/"]
---
Dart 是编程语言王国的新人。
它借鉴了许多其他主流语言,并且不会偏离它的兄弟语言 JavaScript 太多。
就像 JavaScript 一样Dart 的目标是提供良好的浏览器集成。
Dart 最有争议的特性必然是它的可选类型。
```javascript
import "dart:collection";
import "dart:math" as DM;
// 欢迎进入15分钟的 Dart 学习。 http://www.dartlang.org/
// 这是一个可实际执行的向导。你可以用 Dart 运行它
// 或者在线执行! 可以把代码复制/粘贴到这个网站。 http://try.dartlang.org/
// 函数声明和方法声明看起来一样。
// 函数声明可以嵌套。声明使用这种 name() {} 的形式,
// 或者 name() => 单行表达式; 的形式。
// 右箭头的声明形式会隐式地返回表达式的结果。
example1() {
example1nested1() {
example1nested2() => print("Example1 nested 1 nested 2");
example1nested2();
}
example1nested1();
}
// 匿名函数没有函数名。
example2() {
example2nested1(fn) {
fn();
}
example2nested1(() => print("Example2 nested 1"));
}
// 当声明函数类型的参数的时候,声明中可以包含
// 函数参数需要的参数,指定所需的参数名即可。
example3() {
example3nested1(fn(informSomething)) {
fn("Example3 nested 1");
}
example3planB(fn) { // 或者不声明函数参数的参数
fn("Example3 plan B");
}
example3nested1((s) => print(s));
example3planB((s) => print(s));
}
// 函数有可以访问到外层变量的闭包。
var example4Something = "Example4 nested 1";
example4() {
example4nested1(fn(informSomething)) {
fn(example4Something);
}
example4nested1((s) => print(s));
}
// 下面这个包含 sayIt 方法的类声明,同样有一个可以访问外层变量的闭包,
// 就像前面的函数一样。
var example5method = "Example5 sayIt";
class Example5Class {
sayIt() {
print(example5method);
}
}
example5() {
// 创建一个 Example5Class 类的匿名实例,
// 并调用它的 sayIt 方法。
new Example5Class().sayIt();
}
// 类的声明使用这种形式 class name { [classBody] }.
// classBody 中可以包含实例方法和变量,
// 还可以包含类方法和变量。
class Example6Class {
var example6InstanceVariable = "Example6 instance variable";
sayIt() {
print(example6InstanceVariable);
}
}
example6() {
new Example6Class().sayIt();
}
// 类方法和变量使用 static 关键词声明。
class Example7Class {
static var example7ClassVariable = "Example7 class variable";
static sayItFromClass() {
print(example7ClassVariable);
}
sayItFromInstance() {
print(example7ClassVariable);
}
}
example7() {
Example7Class.sayItFromClass();
new Example7Class().sayItFromInstance();
}
// 字面量非常方便,但是对于在函数/方法的外层的字面量有一个限制,
// 类的外层或外面的字面量必需是常量。
// 字符串和数字默认是常量。
// 但是 array 和 map 不是。他们需要用 "const" 声明为常量。
var example8A = const ["Example8 const array"],
example8M = const {"someKey": "Example8 const map"};
example8() {
print(example8A[0]);
print(example8M["someKey"]);
}
// Dart 中的循环使用标准的 for () {} 或 while () {} 的形式,
// 以及更加现代的 for (.. in ..) {} 的形式, 或者
// 以 forEach 开头并具有许多特性支持的函数回调的形式。
var example9A = const ["a", "b"];
example9() {
for (var i = 0; i < example9A.length; i++) {
print("Example9 for loop '${example9A[i]}'");
}
var i = 0;
while (i < example9A.length) {
print("Example9 while loop '${example9A[i]}'");
i++;
}
for (var e in example9A) {
print("Example9 for-in loop '${e}'");
}
example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
}
// 遍历字符串中的每个字符或者提取其子串。
var example10S = "ab";
example10() {
for (var i = 0; i < example10S.length; i++) {
print("Example10 String character loop '${example10S[i]}'");
}
for (var i = 0; i < example10S.length; i++) {
print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
}
}
// 支持两种数字格式 int 和 double 。
example11() {
var i = 1 + 320, d = 3.2 + 0.01;
print("Example11 int ${i}");
print("Example11 double ${d}");
}
// DateTime 提供了日期/时间的算法。
example12() {
var now = new DateTime.now();
print("Example12 now '${now}'");
now = now.add(new Duration(days: 1));
print("Example12 tomorrow '${now}'");
}
// 支持正则表达式。
example13() {
var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$");
match(s) {
if (re.hasMatch(s)) {
print("Example13 regexp matches '${s}'");
} else {
print("Example13 regexp doesn't match '${s}'");
}
}
match(s1);
match(s2);
}
// 布尔表达式必需被解析为 true 或 false
// 因为不支持隐式转换。
example14() {
var v = true;
if (v) {
print("Example14 value is true");
}
v = null;
try {
if (v) {
// 不会执行
} else {
// 不会执行
}
} catch (e) {
print("Example14 null value causes an exception: '${e}'");
}
}
// try/catch/finally 和 throw 语句用于异常处理。
// throw 语句可以使用任何对象作为参数。
example15() {
try {
try {
throw "Some unexpected error.";
} catch (e) {
print("Example15 an exception: '${e}'");
throw e; // Re-throw
}
} catch (e) {
print("Example15 catch exception being re-thrown: '${e}'");
} finally {
print("Example15 Still run finally");
}
}
// 要想有效地动态创建长字符串,
// 应该使用 StringBuffer。 或者 join 一个字符串的数组。
example16() {
var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
for (e in a) { sb.write(e); }
print("Example16 dynamic string created with "
"StringBuffer '${sb.toString()}'");
print("Example16 join string array '${a.join()}'");
}
// 字符串连接只需让相邻的字符串字面量挨着,
// 不需要额外的操作符。
example17() {
print("Example17 "
"concatenate "
"strings "
"just like that");
}
// 字符串使用单引号或双引号做分隔符,二者并没有实际的差异。
// 这种灵活性可以很好地避免内容中需要转义分隔符的情况。
// 例如,字符串内容里的 HTML 属性使用了双引号。
example18() {
print('Example18 <a href="etc">'
"Don't can't I'm Etc"
'</a>');
}
// 用三个单引号或三个双引号表示的字符串
// 可以跨越多行,并且包含行分隔符。
example19() {
print('''Example19 <a href="etc">
Example19 Don't can't I'm Etc
Example19 </a>''');
}
// 字符串可以使用 $ 字符插入内容。
// 使用 $ { [expression] } 的形式,表达式的值会被插入到字符串中。
// $ 跟着一个变量名会插入变量的值。
// 如果要在字符串中插入 $ ,可以使用 \$ 的转义形式代替。
example20() {
var s1 = "'\${s}'", s2 = "'\$s'";
print("Example20 \$ interpolation ${s1} or $s2 works.");
}
// 可选类型允许作为 API 的标注,并且可以辅助 IDE
// 这样 IDE 可以更好地提供重构、自动完成和错误检测功能。
// 目前为止我们还没有声明任何类型,并且程序运行地很好。
// 事实上,类型在运行时会被忽略。
// 类型甚至可以是错的,并且程序依然可以执行,
// 好像和类型完全无关一样。
// 有一个运行时参数可以让程序进入检查模式,它会在运行时检查类型错误。
// 这在开发时很有用,但是由于增加了额外的检查会使程序变慢,
// 因此应该避免在部署时使用。
class Example21 {
List<String> _names;
Example21() {
_names = ["a", "b"];
}
List<String> get names => _names;
set names(List<String> list) {
_names = list;
}
int get length => _names.length;
void add(String name) {
_names.add(name);
}
}
void example21() {
Example21 o = new Example21();
o.add("c");
print("Example21 names '${o.names}' and length '${o.length}'");
o.names = ["d", "e"];
print("Example21 names '${o.names}' and length '${o.length}'");
}
// 类的继承形式是 class name extends AnotherClassName {} 。
class Example22A {
var _name = "Some Name!";
get name => _name;
}
class Example22B extends Example22A {}
example22() {
var o = new Example22B();
print("Example22 class inheritance '${o.name}'");
}
// 类也可以使用 mixin 的形式
// class name extends SomeClass with AnotherClassName {}.
// 必需继承某个类才能 mixin 另一个类。
// 当前 mixin 的模板类不能有构造函数。
// Mixin 主要是用来和辅助的类共享方法的,
// 这样单一继承就不会影响代码复用。
// Mixin 声明在类定义的 "with" 关键词后面。
class Example23A {}
class Example23Utils {
addTwo(n1, n2) {
return n1 + n2;
}
}
class Example23B extends Example23A with Example23Utils {
addThree(n1, n2, n3) {
return addTwo(n1, n2) + n3;
}
}
example23() {
var o = new Example23B(), r1 = o.addThree(1, 2, 3),
r2 = o.addTwo(1, 2);
print("Example23 addThree(1, 2, 3) results in '${r1}'");
print("Example23 addTwo(1, 2) results in '${r2}'");
}
// 类的构造函数名和类名相同,形式为
// SomeClass() : super() {}, 其中 ": super()" 的部分是可选的,
// 它用来传递参数给父类的构造函数。
class Example24A {
var _value;
Example24A({value: "someValue"}) {
_value = value;
}
get value => _value;
}
class Example24B extends Example24A {
Example24B({value: "someOtherValue"}) : super(value: value);
}
example24() {
var o1 = new Example24B(),
o2 = new Example24B(value: "evenMore");
print("Example24 calling super during constructor '${o1.value}'");
print("Example24 calling super during constructor '${o2.value}'");
}
// 对于简单的类,有一种设置构造函数参数的快捷方式。
// 只需要使用 this.parameterName 的前缀,
// 它就会把参数设置为同名的实例变量。
class Example25 {
var value, anotherValue;
Example25({this.value, this.anotherValue});
}
example25() {
var o = new Example25(value: "a", anotherValue: "b");
print("Example25 shortcut for constructor '${o.value}' and "
"'${o.anotherValue}'");
}
// 可以在大括号 {} 中声明命名参数。
// 大括号 {} 中声明的参数的顺序是随意的。
// 在中括号 [] 中声明的参数也是可选的。
example26() {
var _name, _surname, _email;
setConfig1({name, surname}) {
_name = name;
_surname = surname;
}
setConfig2(name, [surname, email]) {
_name = name;
_surname = surname;
_email = email;
}
setConfig1(surname: "Doe", name: "John");
print("Example26 name '${_name}', surname '${_surname}', "
"email '${_email}'");
setConfig2("Mary", "Jane");
print("Example26 name '${_name}', surname '${_surname}', "
"email '${_email}'");
}
// 使用 final 声明的变量只能被设置一次。
// 在类里面final 实例变量可以通过常量的构造函数参数设置。
class Example27 {
final color1, color2;
// 更灵活一点的方法是在冒号 : 后面设置 final 实例变量。
Example27({this.color1, color2}) : color2 = color2;
}
example27() {
final color = "orange", o = new Example27(color1: "lilac", color2: "white");
print("Example27 color is '${color}'");
print("Example27 color is '${o.color1}' and '${o.color2}'");
}
// 要导入一个库,使用 import "libraryPath" 的形式,或者如果要导入的是
// 核心库使用 import "dart:libraryName" 。还有一个称为 "pub" 的包管理工具,
// 它使用 import "package:packageName" 的约定形式。
// 看下这个文件顶部的 import "dart:collection"; 语句。
// 导入语句必需在其它代码声明之前出现。IterableBase 来自于 dart:collection 。
class Example28 extends IterableBase {
var names;
Example28() {
names = ["a", "b"];
}
get iterator => names.iterator;
}
example28() {
var o = new Example28();
o.forEach((name) => print("Example28 '${name}'"));
}
// 对于控制流语句,我们有:
// * 必需带 break 的标准 switch 语句
// * if-else 和三元操作符 ..?..:..
// * 闭包和匿名函数
// * break, continue 和 return 语句
example29() {
var v = true ? 30 : 60;
switch (v) {
case 30:
print("Example29 switch statement");
break;
}
if (v < 30) {
} else if (v > 30) {
} else {
print("Example29 if-else statement");
}
callItForMe(fn()) {
return fn();
}
rand() {
v = new DM.Random().nextInt(50);
return v;
}
while (true) {
print("Example29 callItForMe(rand) '${callItForMe(rand)}'");
if (v != 30) {
break;
} else {
continue;
}
// 不会到这里。
}
}
// 解析 int把 double 转成 int或者使用 ~/ 操作符在除法计算时仅保留整数位。
// 让我们也来场猜数游戏吧。
example30() {
var gn, tooHigh = false,
n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
top = top ~/ 6;
gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive
print("Example30 Guess a number between 0 and ${top}");
guessNumber(i) {
if (n == gn) {
print("Example30 Guessed right! The number is ${gn}");
} else {
tooHigh = n > gn;
print("Example30 Number ${n} is too "
"${tooHigh ? 'high' : 'low'}. Try again");
}
return n == gn;
}
n = (top - bottom) ~/ 2;
while (!guessNumber(n)) {
if (tooHigh) {
top = n - 1;
} else {
bottom = n + 1;
}
n = bottom + ((top - bottom) ~/ 2);
}
}
// 程序的唯一入口点是 main 函数。
// 在程序开始执行 main 函数之前,不期望执行任何外层代码。
// 这样可以帮助程序更快地加载,甚至仅惰性加载程序启动时需要的部分。
main() {
print("Learn Dart in 15 minutes!");
[example1, example2, example3, example4, example5, example6, example7,
example8, example9, example10, example11, example12, example13, example14,
example15, example16, example17, example18, example19, example20,
example21, example22, example23, example24, example25, example26,
example27, example28, example29, example30
].forEach((ef) => ef());
}
```
## 延伸阅读
Dart 有一个综合性网站。它涵盖了 API 参考、入门向导、文章以及更多,
还包括一个有用的在线试用 Dart 页面。
http://www.dartlang.org/
http://try.dartlang.org/