我编译了自己的 AOSP 镜像并得到了这个:
lz@vm:/mnt/android-dev-3/aosp/grapheneos-lz_experiments/out/target/product/generic_x86_64$ ls *.img
cache.img ramdisk.img system.img vendor_boot-debug.img
dtb.img ramdisk-qemu.img system-qemu.img vendor_boot.img
encryptionkey.img super_empty.img userdata.img vendor.img
ramdisk-debug.img super.img vbmeta.img vendor-qemu.img
Run Code Online (Sandbox Code Playgroud)
我知道我不需要自己指定 .img,AOSP 预构建模拟器就可以工作,但我想用于其他目的。
所以我做了DIR_OUT = /mnt/android-dev-3/aosp/grapheneos-lz_experiments/out/target/product/generic_x86_64
./emulator -sysdir $DIR_OUT/system -datadir $DIR_OUT/data -kernel $DIR_OUT/kernel-ranchu -ramdisk $DIR_OUT/ramdisk.img -system $DIR_OUT/system.img -data $DIR_OUT/userdata.img -cache $DIR_OUT/cache.img -vendor $DIR_OUT/vendor.img
emulator: ERROR: No AVD specified. Use '@foo' or '-avd foo' to launch a virtual device named 'foo'
emulator: WARNING: userdata partition is resized from 550 M to 800 M
emulator: WARNING: …Run Code Online (Sandbox Code Playgroud) 我试图在线程之间共享一个函数,可以用另一个函数来调用它:
fn main() {
let on_virtual_tun_write = std::sync::Arc::new(|f: &dyn FnOnce(&mut [u8]), size: usize|-> std::result::Result<(),()>{
let mut buffer = vec![0; size];
f(buffer.as_mut_slice());
Ok(())
});
}
Run Code Online (Sandbox Code Playgroud)
一旦被调用,它就会使用f传递的参数作为参数来检索缓冲区。正如你所看到的,我并不打算复制该函数,我只是在有人调用闭包时立即使用它,然后丢弃它。然而,Rust 认为我想复制它。我该怎么做才能告诉 Rust 我只想使用函数的引用?我以为&dyn就足够了。
错误:
error[E0161]: cannot move a value of type dyn for<'r> FnOnce(&'r mut [u8]): the size of dyn for<'r> FnOnce(&'r mut [u8]) cannot be statically determined
--> src/main.rs:4:9
|
4 | f(buffer.as_mut_slice());
| ^
error[E0507]: cannot move out of `*f` which is behind a shared reference
--> src/main.rs:4:9
| …Run Code Online (Sandbox Code Playgroud) 有些人做
#[cfg(test)]
mod tests {
//all tests here
}
Run Code Online (Sandbox Code Playgroud)
虽然简单地将每个测试放在文件的末尾,例如
#[test]
fn test1() {
}
#[test]
fn test2() {
}
Run Code Online (Sandbox Code Playgroud)
也可以工作,我什至可以通过货物运行单个测试。
有什么不同?为什么有些人会用第一种方式?
有时我会与生命作斗争。我还在学习,我不知道这里发生了什么:
use std::future::Future;
use futures::future::{BoxFuture, FutureExt};
struct M{}
struct Client{}
impl Client {
async fn send_and_expect<'a>(
&'a mut self,
m: &M
) -> std::result::Result<(), ()> {
Ok(())
}
pub fn connection_retrier<'a, T>(
f: fn(&'a mut Self, &M) -> T,
f_self: &'a mut Self,
f_m: &'a M,
)-> BoxFuture<'a, std::result::Result<(),()>>
where
T: Future<Output = std::result::Result<(), ()>> + 'a
{
async move {
Client::send_and_expect(f_self, f_m).await
}.boxed()
}
async fn send_with_retry<'a>(&'a mut self) -> std::result::Result<(), ()> {
let m = M{};
Client::connection_retrier(
Client::send_and_expect, …Run Code Online (Sandbox Code Playgroud) 我在异步中使用递归时遇到了一个奇怪的错误。
我可以client在async. 但是,如果我do_something再次打电话,它会抱怨std::sync::MutexGuard<'_, Client>没有被发送。我认为它正在尝试发送c到另一个线程。我以为do_something在一个线程中执行,然后do_something(client.clone()).await在另一个线程中执行。我不明白为什么c要从async线程转移到这个新线程。
use std::sync::{Arc, Mutex};
use std::future::Future;
use futures::future::{BoxFuture, FutureExt};
struct Client{
}
impl Client {}
fn do_something<'a>(
client: Arc<Mutex<Client>>,
) -> BoxFuture<'a, std::result::Result<(), ()>> {
async move {
let c = client.lock().unwrap();
do_something(client.clone()).await;
Ok(())
}.boxed()
}
fn main() {
let c = Arc::new(Mutex::new(Client{}));
do_something(c.clone());
}
Run Code Online (Sandbox Code Playgroud)
错误:
error: future cannot be sent between threads safely
--> src/main.rs:17:7
|
17 | …Run Code Online (Sandbox Code Playgroud) 我找到了这段代码:
std::string(avdInfo_getSystemImagePath(m_avd)
?: avdInfo_getSystemInitImagePath(m_avd))
Run Code Online (Sandbox Code Playgroud)
我只找到了有关条件运算符的信息:http : //www.cplusplus.com/articles/1AUq5Di1/
那是, ?和 : 是分开的。但是,当他们在一起时,这意味着什么?既avdInfo_getSystemImagePath与avdInfo_getSystemInitImagePath回报char*
我已经读完了 Existential Types Wikibook,它比较forall了使用小写字母来定义泛型类型。然后它说真正的用处forall是当你将它与类型类一起使用时。也就是说,forall让您的函数可以使用许多符合某种类型类的类型。
例子:
data ShowBox = forall s. Show s => SB s
Run Code Online (Sandbox Code Playgroud)
好吧,我发现了一个真正的世界用法:
spock :: forall conn sess st. SpockCfg conn sess st ->
SpockM conn sess st () -> IO Middleware
<Source>
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到,在它使用但没有类型类约束的源代码中forall:
spock :: forall conn sess st. SpockCfg conn sess st ->
SpockM conn sess st () -> IO Wai.Middleware
spock spockCfg spockAppl =
do connectionPool <-
case poolOrConn of
PCNoDatabase -> …Run Code Online (Sandbox Code Playgroud) 我有以下类型:
pub type MessageStream = Pin<Box<dyn Stream<Item = Result<rtsp_types::Message<Body>, ReadError>> + Send>>;
Run Code Online (Sandbox Code Playgroud)
和一个结构成员:
stream: Option<MessageStream>,
Run Code Online (Sandbox Code Playgroud)
我这样称呼:
self.stream.as_mut().unwrap().poll_next();
Run Code Online (Sandbox Code Playgroud)
但我得到
116 | let response = self.stream.as_mut().unwrap().poll_next();
| ^^^^^^^^^ method not found in `&mut Pin<Box<(dyn futures::Stream<Item = std::result::Result<rtsp_types::Message<Body>, message_socket::ReadError>> + std::marker::Send + 'static)>>`
Run Code Online (Sandbox Code Playgroud)
在https://docs.rs/futures/0.2.0/futures/stream/trait.Stream.html上,它仅列出poll_next,但into_future()由于某种原因对我有用。
转向未来很好,但我也想这样做poll_next,我正在尝试很多事情。
怎么了?
在https://wiki.haskell.org/99_questions/Solutions/5 上,有一个反转列表的解决方案:
reverse :: [a] -> [a]
reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
Run Code Online (Sandbox Code Playgroud)
然而,这个定义比 Prelude 中的定义更浪费,因为它在累积结果时反复重新计算。以下变体避免了这种情况,因此在计算上更接近 Prelude 版本。
reverse :: [a] -> [a]
reverse list = reverse' list []
where
reverse' [] reversed = reversed
reverse' (x:xs) reversed = reverse' xs (x:reversed)
Run Code Online (Sandbox Code Playgroud)
我试图了解两者之间的区别。什么reconses意思?
我的想法是reverse xs ++ [x]从第一个元素到最后一个元素,然后添加x,这需要n迭代 ( n= lenght of xs)。在第二个中,它将列表的其余部分附加到x. 但我不知道 Haskell 的内部结构,不知道它与其他示例有何不同。
究竟会发生什么?
我认为一切都是 Haskell 中的函数。例如:
sum :: Int -> Int
sum a b = a+b
Run Code Online (Sandbox Code Playgroud)
但是有这样的事情:
tom :: Reader String String
Run Code Online (Sandbox Code Playgroud)
这究竟是什么意思?什么是tom?一个什么都得不到并返回的函数Reader String String?