BMW互聯(lián)駕駛作為一個集成整合系統(tǒng),成功地將iDrive原有的信息與眾多駕駛員輔助功能集成到了一起,并提供諸如互聯(lián)網(wǎng)服務(wù)、交通信息查詢、緊急救援協(xié)助、旅程咨詢、道路救援、信息、咨詢在線以及客戶關(guān)懷中心等功能。
但有的車主說他的互聯(lián)駕駛功能無法使用,那么接下來,就給這些車主答疑解惑。
首先打開“云端互聯(lián)”的APP查看如圖所示的車輛,車罩是否已打開。
1.如圖沒有打開,請聯(lián)系您的銷售顧問,并詢問您的車輛是否已上報銷售
2.若已打開并顯示您的車型,請看下一頁的具體操作
01
在主界面選擇并進入“互聯(lián)駕駛”的選項
02
進入互聯(lián)駕駛界面后,按下iDrive控制器右下角的“option”快捷鍵
03
按下“option”按鈕后會進入如圖所示的這樣一個子菜單。選中“更新BMW服務(wù)”選項并按下iDrive控制器確認
04
等待在線更新完成(確保車輛停在露天的安全位置),更新成功后顯示器會顯示“數(shù)據(jù)傳輸成功”字樣
若出現(xiàn)更新失敗的情況,建議客戶換一個地方執(zhí)行上述步驟,用以排除特定地點的信號干擾。多次更換地點后仍失敗,則致電0451-8463 5555以尋求更多幫助
更新成功后,離開車輛并上鎖。等待10分鐘以使車輛休眠,然后重新上車查看互聯(lián)駕駛內(nèi)相應(yīng)功能
注:首次使用APP遙控車輛功能需等待較長時間
創(chuàng)新、成功、前瞻、責(zé)任、可持續(xù)
我在學(xué)習(xí)Rust時,注意到有4個概念經(jīng)常放到一起討論:Result、Option、unwapr和?操作符。 本文記錄了我對這4個Rust概念的思考,這個思考過程幫助我理解并學(xué)會了如何寫出更地道的Rust代碼。
區(qū)塊鏈開發(fā)教程鏈接: 以太坊 | 比特幣 | EOS | Tendermint | Hyperledger Fabric | Omni/USDT | Ripple
雖然Rust中有null的概念,但是使用null并不是Rust中常見的模式。假設(shè)我們要 寫一個函數(shù),輸入一種手機操作系統(tǒng)的名稱,這個函數(shù)就會返回其應(yīng)用商店的名稱。 如果傳入字符串iOS,該函數(shù)將返回App Store;如果傳入字符串a(chǎn)ndroid,那么該函數(shù)將返回 Play Store。任何其他的輸入都被視為無效。
在大多數(shù)開發(fā)語言中,我們可以選擇返回null或字符串invalid來表示無效的結(jié)果, 不過這不是Rust的用法。
地道的Rust代碼應(yīng)該讓該函數(shù)返回一個Option。Option或更確切的說Option<T> 是一個泛型,可以是Some<T>或None(為了便于閱讀,后續(xù)文章中將省略類型參數(shù)T)。 Rust將Some和None稱為變體(Variant) —— 這一概念在其他語言中并不存在,因此我也不 去定義到底什么是變體了。
在我們的示例中,正常情況下函數(shù)將返回包裹在Some變體中的字符串常量 App Store或Play Store。而在非正常情況下,函數(shù)將返回None。
fn find_store(mobile_os: &str) -> Option<&str> {
match mobile_os {
"iOS"=> Some("App Store"),
"android"=> Some("Play Store"),
_=> None
}
}
要使用find_store(),我們可以用如下方式調(diào)用:
fn main() {
println!("{}", match find_store("windows") {
Some(s)=> s,
None=> "Not a valid mobile OS"
});
}
完整的代碼如下:
fn find_store(mobile_os: &str) -> Option<&str> {
match mobile_os {
"iOS"=> Some("App Store"),
"android"=> Some("Play Store"),
_=> None
}
}
fn main() {
println!("{}", match find_store("windows") {
Some(s)=> s,
None=> "Not a valid mobile OS"
});
}
Result,或者更確切地說Result<T,E>,是和Rust中的Option相關(guān)的概念, 它是一個加強版本的Option。
Result<T, E>可能有以下結(jié)果之一:
與之前我們看到Option可以包含Some或None不同,Result中包含了錯誤 相關(guān)信息,這是Option中所沒有的。
讓我們看一個函數(shù)實例,它返回一個Result。該函數(shù)摘自用于解析JSON字符串的 serde_json庫,其簽名為:
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
where
T: Deserialize<'a>,
假設(shè)我們要解析如下的字符串:
let json_string=r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
目標(biāo)是解析為Rust的一個person結(jié)構(gòu)對象:
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
解析過程的Rust代碼如下:
let p:Person=match serde_json::from_str(json_string) {
Ok(p)=> p,
Err(e)=> ... //we will discuss what goes here next
};
正常情況下可以得到期望的結(jié)果。不過假設(shè)在輸入的json_string中 有一個筆誤,這導(dǎo)致程序運行時將執(zhí)行Err分支。
當(dāng)碰到Err時,我們可以采取兩個動作:
在上面的示例中,假設(shè)我們期望panic!:
let p: Person=match serde_json::from_str(data) {
Ok(p)=> p,
Err(e)=> panic!("cannot parse JSON {:?}, e"), //panic
}
當(dāng)碰到Err時,上面的代碼panic!就會崩掉整個程序,也許這不是你期望的。 我們可以修改為:
let p:Person=serde_json::from_str(data).unwrap();
如果我們可以確定輸入的json_string始終會是可解析的,那么使用unwrap 沒有問題。但是如果會出現(xiàn)Err,那么程序就會崩潰,無法從故障中恢復(fù)。 在開發(fā)過程中,當(dāng)我們更關(guān)心程序的主流程時,unwrap也可以作為快速 原型使用。
因此unwrap隱含了panic!。雖然與更顯式的版本沒有差異,但是危險在于 其隱含特性,因為有時這并不是你真正期望的行為。
無論如何,如果我們需要調(diào)用panic!,代碼如下:
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn typed_example() -> Result<()> {
//age2 is error on purpose
let data=r#"
{
"name": "John Doe",
"age2": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let p:Person=serde_json::from_str(data).unwrap();
println!("Please call {} at the number {}", p.name, p.phones[0]);
Ok(())
}
fn main() {
match typed_example() {
Ok(_)=> println!("program ran ok"),
Err(_)=> println!("program ran with error"),
}
}
當(dāng)碰到Err時,我們不一定要panic!,也可以返回Err。不是每個Err都是不可恢復(fù)的, 因此有時并不需要panic!。下面的代碼返回Err:
let p: Person=match serde_json::from_str(data) {
Ok(p)=> p,
Err(e)=> return Err(e.into()),
};
?操作符提供了一個更簡潔的方法來替換上面的代碼:
let p:Person=serde_json::from_str(data)?;
這時完整的Rust程序代碼如下:
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn typed_example() -> Result<()> {
//age2 is error on purpose
let data=r#"
{
"name": "John Doe",
"age2": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let p: Person=serde_json::from_str(data)?;
println!("Please call {} at the number {}", p.name, p.phones[0]);
Ok(())
}
fn main() {
match typed_example() {
Ok(_)=> println!("program ran ok"),
Err(e)=> println!("program ran with error {:?}", e),
}
}
就像我們可以使用unwarp和?來處理Result,我們也可以使用unwrap和?來處理Option。
如果我們unwrap的Option的值是None,那么程序就會panic!。示例如下:
fn next_birthday(current_age: Option<u8>) -> Option<String> {
// If `current_age` is `None`, this returns `None`.
// If `current_age` is `Some`, the inner `u8` gets assigned to `next_age` after 1 is added to it
let next_age: u8=current_age?;
Some(format!("Next year I will be {}", next_age + 1))
}
fn main() {
let s=next_birthday(None);
match s {
Some(a)=> println!("{:#?}", a),
None=> println!("No next birthday")
}
}
原文鏈接:http://blog.hubwiz.com/2020/06/15/rust-result-option-unwrap-question/