我正在学习Rust,我有一个简单的程序,我希望用它作为学习练习。我在这里的目的是为了更好地了解做事的正确方法。
我试图使用fastq crate来做一些fastq文件的操作-这些是简单的文本文件,是存储高通量[DNA/RNA]测序数据的标准。我想做的是修改条目的一个子集,并将修改后的条目写入一个文件。
现在我有一个最初的概念证明,下面的工作来修改每个质量值的第一个字节。我想确定我做的事情是否明智。我的总体思路:
- 使用fastq::RefRecord::to_owned_record()来创建记录的副本,我将拥有 的所有权
- 从质量字段字节片创建bytes::BytesMut
- 修改BytesMut的字节数
- 从修改的BytesMut中设置my OwnedRecord中的质量字段
- 验证是否已设置
上面的过程和下面的代码看起来合理吗?有些事情你会做得不一样吗?为什么?由于我是Rust新手,我觉得我可能以一种幼稚和次优的方式看待事物。让我知道你的总体想法。
依赖性:
<- 字节/gh>
- fastq
下面是我的示例代码:
use bytes::BytesMut;
use fastq::{Parser, parse_path, Record, RefRecord};
use std::env::args;
const READS: &str = r#"@read1/ENST00000266263.10;mate1:84-183;mate2:264-363
GACAGCCAGGGGCCAGCGGGTGGCAGTGCCCAGGACATAGAGAGAGGCAGCACACACGCGGTTGATGGTGAAGCCCGGAATGGCCACAGAGGCTAGAGCC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read2/ENST00000266263.10;mate1:163-262;mate2:283-382
GATGCCATTGACAAAGGCAAGAAGGCTGGAGAGGTGCCCAGCCCTGAAGCAGGCCGCAGCGCCAGGGTGACTGTGGCTGTGGTGGACACCTTTGTATGGC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read3/ENST00000266263.10;mate1:86-185;mate2:265-364
GGACAGCCAGGGGCCAGCGGGTGGCAGTGCCCAGGACATAGAGAGAGGCAGCANACACACGGTTGATGGTGAAGCCCGGAATGGCCACAGAGGCTAGAGC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read4/ENST00000266263.10;mate1:297-396;mate2:401-500
CAGGAGGAGCTGGGCTTCCCCACTGTTAGGTAGAGCTTGCGCAGGCTGGAGTCCAGGAGGAAATCCACCGACCTGTCAATGGGGTGGATAATGATGGGGA
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
"#;
fn main() {
let mut total: usize = 0;
let parser = Parser::new(READS.as_bytes());
parser.each(|record| {
println!("Before mod");
println!("{}", String::from_utf8_lossy(record.qual()));
let mut owned_rec = RefRecord::to_owned_record(&record);
let mut curr_bytes = BytesMut::from(owned_rec.qual());
curr_bytes[0] = b'$';
owned_rec.qual = curr_bytes.to_vec();
println!("After mod");
println!("{}", String::from_utf8_lossy(owned_rec.qual()));
total += 1;
true
}).expect("Invalid fastq file");
println!("{}", total);
}
另外,我希望将这个过程移动到一个函数中,所以我想知道这样做的最佳过程。我在想一个函数modify_qual
,它可以为我完成这个。对于这样的东西,你的函数签名是什么样的?也许是使用记录并返回修改后的记录的东西?别的吗?我理解可变性的概念,在表面上通过引用,但对于何时做某些事情没有一个好的心理模型。
提前感谢您的帮助!
关于你的问题"你的函数签名会是什么样子"这些东西在开发过程中会发生变化,所以没必要在上面花太多时间,
我做了2个方法代码如下,
use bytes::BytesMut;
use fastq::{Parser, Record, RefRecord};
const READS: &str = r#"@read1/ENST00000266263.10;mate1:84-183;mate2:264-363
GACAGCCAGGGGCCAGCGGGTGGCAGTGCCCAGGACATAGAGAGAGGCAGCACACACGCGGTTGATGGTGAAGCCCGGAATGGCCACAGAGGCTAGAGCC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read2/ENST00000266263.10;mate1:163-262;mate2:283-382
GATGCCATTGACAAAGGCAAGAAGGCTGGAGAGGTGCCCAGCCCTGAAGCAGGCCGCAGCGCCAGGGTGACTGTGGCTGTGGTGGACACCTTTGTATGGC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read3/ENST00000266263.10;mate1:86-185;mate2:265-364
GGACAGCCAGGGGCCAGCGGGTGGCAGTGCCCAGGACATAGAGAGAGGCAGCANACACACGGTTGATGGTGAAGCCCGGAATGGCCACAGAGGCTAGAGC
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
@read4/ENST00000266263.10;mate1:297-396;mate2:401-500
CAGGAGGAGCTGGGCTTCCCCACTGTTAGGTAGAGCTTGCGCAGGCTGGAGTCCAGGAGGAAATCCACCGACCTGTCAATGGGGTGGATAATGATGGGGA
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
"#;
fn main() {
let mut total: usize = 0;
let parser = Parser::new(READS.as_bytes());
parser
.each(|record| {
// modify_qual1(record, &mut total)
println!("Before mod");
println!("{}", String::from_utf8_lossy(record.qual()));
let owned_rec = modify_qual(record);
println!("After mod");
println!("{}", String::from_utf8_lossy(owned_rec.qual()));
total += 1;
true
})
.expect("Invalid fastq file");
println!("{}", total);
}
fn modify_qual(record: RefRecord) -> fastq::OwnedRecord {
let mut owned_rec = RefRecord::to_owned_record(&record);
let mut curr_bytes = BytesMut::from(owned_rec.qual());
curr_bytes[0] = b'$';
owned_rec.qual = curr_bytes.to_vec();
owned_rec
}
fn modify_qual1(record: RefRecord, total: &mut usize) -> bool {
println!("Before mod");
println!("{}", String::from_utf8_lossy(record.qual()));
let mut owned_rec = RefRecord::to_owned_record(&record);
let mut curr_bytes = BytesMut::from(owned_rec.qual());
curr_bytes[0] = b'$';
owned_rec.qual = curr_bytes.to_vec();
println!("After mod");
println!("{}", String::from_utf8_lossy(owned_rec.qual()));
*total += 1;
true
}