| Swift | C++
:-:|:-:|:-:
關(guān)鍵字 | let / var | const auto / auto
作用 | 創(chuàng)建一個(gè)常量/變量 | 創(chuàng)建一個(gè)常量/** 變量**
關(guān)于數(shù)值
Swift 中使用 let
來創(chuàng)建常量,使用var
來創(chuàng)建變量.
var myVariable = 42
myVariable = 50
let myConstant = 42
C++ 中可以使用 auto
創(chuàng)建變量, 使用const auto
創(chuàng)建常量(也可以用其他形式創(chuàng)建變量).
#include <iostream>
int main() {
auto myVariable = 42;
myVariable = 50;
const auto myConstant = 42;
return 0;
}
const
是 類型說明符, 用于說明后面那個(gè)東西是常量, 初次賦值之后就再也不能改變了.
你不需要指明常量或變量的類型, 在聲明和同時(shí)賦值的話, 編譯器可以自動推斷類型.
上面例子中的 myVariable
和 myConstant
:
- Swift 將它們推斷為
Int
類型. - C++ 將它們推斷為
int
類型.
一個(gè)常量或變量的值, 在編譯期并不需要明確的值. 但是如果沒有提供足夠的信息(或者沒有初始值), 那么你需要顯式的指明類型.
Swift 中可以在變量或常量右面聲明類型, 用冒號:
分隔:
var varValue: Int
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
C++中則需要先寫類型名,再寫變量名(創(chuàng)建常量/變量的另外的形式):
#include <iostream>
int main() {
int varValue;
const int constImplicitInt = 70;
const double constImplicitDouble = 70.0;
return 0;
}
Swift 練習(xí): 創(chuàng)建一個(gè)常量幼东,顯式指定類型為 Float 并指定初始值為4温峭。
C++ 練習(xí): 創(chuàng)建一個(gè)常量啡直,顯式指定類型為 float 并指定初始值為4庵佣。
關(guān)于字符串
Swift 中的值永遠(yuǎn)不會被隱式轉(zhuǎn)換為其他類型. 如果你需要把一個(gè)值轉(zhuǎn)換為其他類型, 請顯式轉(zhuǎn)換:
let label = "The width is "
let width = 94
let widthLabel = label + String(width)
刪除 String 試試看? 錯誤提示是什么?
** C++中**的值可以被隱式轉(zhuǎn)換為其他類型, 但并不是所有類型的值都可以. 只有該類型支持隱式轉(zhuǎn)換為其他類型, 才可以把該類型的值隱式轉(zhuǎn)換為其他類型:
#include <iostream>
#include <string> // 創(chuàng)建一個(gè)字符串變量,需要先包含 string 頭文件
int main() {
int intValue = 70;
double doubleValue = intValue;
std::string aCplusplusString = "a C string"; // std::string 表示使用在標(biāo)準(zhǔn)庫 std 中的 string 類型
return 0;
}
把
std::string aCplusplusString = "a C string";
寫成std::string aCplusplusString = doubleValue;
試試?
錯誤提示是什么?
Swift 中有一種把值轉(zhuǎn)換成字符串的更簡單的方法: 把值寫到括號中,然后在括號前寫一個(gè)反斜杠. 形如: "字符串內(nèi)容\(值)字符串其他內(nèi)容"
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."
** C++中**這種數(shù)值向字符串的轉(zhuǎn)換是由標(biāo)準(zhǔn)庫函數(shù) to_string
來完成的:
#include <iostream>
#include <string> // 創(chuàng)建一個(gè)字符串變量,需要先包含 string 頭文件
int main() {
int intValue = 70;
double doubleValue = intValue;
std::string aCplusplusString = "a C string"; // std::string 表示使用在標(biāo)準(zhǔn)庫 std 中的 string 類型
auto otherString = std::to_string(doubleValue); // std::to_string 表示使用在標(biāo)準(zhǔn)庫 std 中的 to_string 函數(shù)
auto otherString2 = std::to_string(doubleValue + intValue);
return 0;
}
Swift練習(xí):使用 \( )來把一個(gè)浮點(diǎn)數(shù)轉(zhuǎn)換成字符串, 并加上某人的名字
C++練習(xí):使用標(biāo)準(zhǔn)庫中的 to_string 函數(shù)來把浮點(diǎn)數(shù)轉(zhuǎn)換成字符串
關(guān)于數(shù)組與集合
** Swift 中**可以使用方括號[ ]
來創(chuàng)建數(shù)組或字典, 并使用下標(biāo)或者鍵來訪問元素. 最后一個(gè)元素后面允許有逗號.
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
// 創(chuàng)建空數(shù)組或字典,可以使用初始化語法.
let emptyArray = [String]()
let emptyDictionary = [String: Float]()
// 如果類型信息可以推斷出來, 可以使用[]創(chuàng)建空數(shù)組,使用[:]創(chuàng)建空字典.
// 當(dāng)你為一個(gè)變量設(shè)置新值或者給一個(gè)函數(shù)傳遞參數(shù)的時(shí)候就可以這樣做
shoppingList = []
occupations = [:]
** C++中**創(chuàng)建向量或關(guān)聯(lián)數(shù)組, 則需要先指明類型名, 然后在<>
中指定元素的類型, 再寫變量名, 然后給變量初始化或賦值. 初始化或賦值時(shí), 最后一個(gè)元素后面也允許有逗號. 只是沒有Swift這么簡潔了:
#include <iostream>
// 注意, 在 C++ 中, 下面這些東西統(tǒng)稱為容器.
#include <string> // 包含 string 來創(chuàng)建C++字符串
#include <vector> // 包含 vector 來創(chuàng)建向量(類似數(shù)組), 另外也可以包含 array 來創(chuàng)建C++數(shù)組, 當(dāng)然什么也不包含, 直接創(chuàng)建 C 數(shù)組
#include <map> // 包含 map 來創(chuàng)建有序的不重復(fù)關(guān)聯(lián)數(shù)組. 另外也可以包含 unordered_map抛蚤、 multimap、 unordered_map_multimap來分別創(chuàng)建無序的不重復(fù)的關(guān)聯(lián)數(shù)組、有序的可重復(fù)的關(guān)聯(lián)數(shù)組喂江、 無序的可重復(fù)的關(guān)聯(lián)數(shù)組
int main() {
// 在創(chuàng)建的時(shí)候就不能使用 auto 進(jìn)行類型推斷了, 需要先指明類型, 再寫變量名
std::string aCArray[4] = {"catfish", "water", "tulips", "blue paint"}; // 創(chuàng)建 C 數(shù)組
aCArray[1] = "bottle of water";
// 創(chuàng)建 vector 需要在<>中指明 vector 中包含元素的類型
std::vector<std::string> aVector = {"catfish", "water", "tulips", "blue paint"};
aVector[1] = "bottle of water";
// 創(chuàng)建 map 需要在<>中分別指明 map 鍵和值的類型
std::map<std::string, std::string> aMap = {
{"Malcolm", "Captain"},
{"Kaylee", "Mechanic"},
}; // std::map<std::string, std::string> 表示使用 std 標(biāo)準(zhǔn)庫中的無序的關(guān)聯(lián)數(shù)組, 其中鍵值的類型分別使用標(biāo)準(zhǔn)庫 std 中的 string
aMap["Jayne"] = "Public Relations";
// 創(chuàng)建空向量/數(shù)組以及空字典
std::vector<std::string> aEmptyArray;
std::map<std::string, std::string> aEmptyMap;
// 現(xiàn)在可以使用 auto 了
auto aCArray2 = aCArray;
auto aMap2 = aMap;
return 0;
}
解釋
-
命名空間
-
C++中的命名空間是為了防止名字沖突, 給防止名字沖突提供了更加可控的機(jī)制.
代碼std::string
, 其中::
是作用域運(yùn)算符,::
運(yùn)算符把它的左右兩邊符號組合在一起, 表示使用在它的左邊符號所代表的命名空間中(std
), 找到的它的右邊符號string
; 也就是說std::string
表示使用存在在std
中的string
如果::
的左邊什么都沒有, 如::something
表示使用在全局作用域中的something
-
Swift 中的命名空間是基于模塊(module)的, 每個(gè) module 代表了 Swift 中的一個(gè)命名空間, 而同一個(gè)命名空間中的名字仍然不能沖突. 簡單的說一個(gè)項(xiàng)目,一個(gè)庫就是一個(gè)命名空間, 而在一個(gè)項(xiàng)目(命名空間)中所用名字哪里都可以使用, 不需要 Import.
另一種策略是使用類型嵌套的方法來指定訪問的范圍.
詳細(xì)請看>>王巍 (@ONEVCAT): 命名空間
-
C++中的命名空間是為了防止名字沖突, 給防止名字沖突提供了更加可控的機(jī)制.
-
C++代碼中那些看起來巨長的類型名字
- 現(xiàn)代 C++語言實(shí)際上是由三部分組成的:
低級語言, 大部分繼承自 C語言. 比如:可以創(chuàng)建 C 數(shù)組
std::string aCArray[4] = {...};
現(xiàn)代高級語言特性, 允許我們定義自己的類型以及組織大規(guī)模程序和系統(tǒng).
標(biāo)準(zhǔn)庫, 它利用高級特性來提供有用的數(shù)據(jù)結(jié)構(gòu)和算法.
比如:vector
,string
,map
就是標(biāo)準(zhǔn)庫提供的,所以如果沒有任何說明的話, 就需要使用::
運(yùn)算符來使用來自標(biāo)準(zhǔn)庫中內(nèi)容(vector
,string
,map
等).
而標(biāo)準(zhǔn)庫的命名空間的名字為std
, 所以才出現(xiàn)像std::string
,std::vector
,std::map
這樣的代碼
- 現(xiàn)代 C++語言實(shí)際上是由三部分組成的:
-
使用 using 聲明等方法避免巨長的類型名字的書寫.
例如寫入:using namespace std;
后就可直接使用 string,vector, map 等名字了, 當(dāng)然還有其他方法, 以后再詳細(xì)介紹- 比如上面的代碼可以修改為:
- 比如上面的代碼可以修改為:
include <iostream>
// 注意, 在 C++ 中, 下面這些東西統(tǒng)稱為容器.
include <string> // 包含 string 來創(chuàng)建字符串
include <vector> // 包含 vector 來創(chuàng)建向量(類似數(shù)組), 另外也可以包含 array 來創(chuàng)建C++數(shù)組, 當(dāng)然也可以聲明也不包含直接創(chuàng)建 C 數(shù)組, 其實(shí) string 是一種字符數(shù)組
include <map> // 包含 map 來創(chuàng)建有序的不重復(fù)關(guān)聯(lián)數(shù)組. 另外也可以包含 unordered_map妒潭、 multimap悴能、 unordered_map_multimap來分別創(chuàng)建無序的不重復(fù)的關(guān)聯(lián)數(shù)組、有序的可重復(fù)的關(guān)聯(lián)數(shù)組雳灾、 無序的可重復(fù)的關(guān)聯(lián)數(shù)組
using namespace std; // 表示在下面的代碼中可以直接使用來自命名空間 std 中的所有名字
int main() {
// 在創(chuàng)建的時(shí)候就不能使用 auto 進(jìn)行類型推斷了, 需要先指明類型, 再寫變量名
string aCArray[4] = {"catfish", "water", "tulips", "blue paint"}; // 創(chuàng)建 C 數(shù)組
aCArray[1] = "bottle of water";
// 創(chuàng)建 vector 需要在<>中指明 vector 中包含元素的類型
vector<string> aVector = {"catfish", "water", "tulips", "blue paint"};
aVector[1] = "bottle of water";
// 創(chuàng)建 map 需要在<>中分別指明 map 鍵和值的類型
map<string, string> aMap = {
{"Malcolm", "Captain"},
{"Kaylee", "Mechanic"},
}; // std::map<std::string, std::string> 表示使用 std 標(biāo)準(zhǔn)庫中的無序的關(guān)聯(lián)數(shù)組, 其中鍵值的類型分別使用標(biāo)準(zhǔn)庫 std 中的 string
aMap["Jayne"] = "Public Relations";
// 創(chuàng)建空向量/數(shù)組以及空字典
vector<string> aEmptyArray;
map<string, string> aEmptyMap;
// 現(xiàn)在可以使用 auto 了
auto aCArray2 = aCArray;
auto aMap2 = aMap;
return 0;
}
```