rust - Do I need any of the *variantType markers? -


i'm trying interact type-unsafe c library in type-safe way rust. c interface deals void pointers. specifically, there write , read function takes such void pointer parameter , obvious things (write given data place else or read place given buffer). kind of data is, agreed upon earlier py bassing integer value open function

1 = float 2 = int32_t 4 = int16_t etc... 

i represent opened output stream (where user can call write on) parameterized rust struct one:

pub struct outputstream<t> {     c_stream: *mut () }  impl<t: valuetype> outputstream<t> {     pub fn write(&mut self, data: &[t]) -> result<(),someerrortype> {         unsafe { ... }     } } 

where valuetype trait wrote supported value types in way nobody else can implement (private base trait trick). so, t not mentioned anywhere within struct. seems case contravarianttype marker. don't understand these type markers. visiting wikipedia page on variance not help. don't see connection between variance , how applies rust's type parameters. , don't know kind of marker prevent.

so questions are: need 1 of these markers outputstream? if so, 1 , why? prevent using it? same goes inputstream provides read method instead of write method.

in general, variance determines subtyping relationship between parameterized types regard parameters:

covariance:      t <: u    =>    f[t] <: f[u] contravariance:  t <: u    =>    f[u] <: f[t] invariance:      t <: u    =>    neither of above bivariance:      t <: u    =>    both of above 

your type is naturally contravariant: methods consume values of type t, not produce them; so-called consumer type. however, subtyping in rust limited; far know, types allow subtyping relationship of kind references (for example, can pass &'static str &'a str variable because 'static lifetime greater or equal other lifetime, &'static str subtype of &'a str 'a).

so, if understand correctly, need variance annotation. if t parameter can reference, use contravarianttype, this:

fn push_something_to(os: outputstream<&'static str>) { ... }  let s: outputstream<&'a str> = ...;  // , 'a less 'static push_something_to(s);   // safe because &'static str valid &'a str 

but couldn't this:

let s: outputstream<int> = ...; push_something_to(s);   // oops, push_something_to expects stream of &'static str 

with invarianttype both forbidden.


however, there seems deep misunderstanding on side, because neither code in documentation on variance markers, nor own code not work in current rust me:

use std::ptr; use std::mem;  struct s<t> { x: *const () }  fn get<t>(s: &s<t>, v: t) {    unsafe {        let x: fn(t) = mem::transmute(s.x);        x(v)    } }  fn main() {     let s: s<int> = s { x: ptr::null() };     get::<box<int>>(&s, box 1); } 

according documentation, should compile due parameterized types being bivariant default, doesn't: acts if parameter invariant.

and own example:

#![allow(dead_code)]  type f<t> = fn(t);  fn test_1<'a>(f: f<&'a str>) -> f<&'static str> {     f }  struct s<t> {     _m: std::kinds::marker::contravarianttype<t> }  fn test_2<'a>(s: s<&'a str>) -> s<&'static str> {     s }  fn main() {} 

as far understand, program should compile, doesn't:

<anon>:9:5: 9:6 error: mismatched types: expected `s<&'static str>` found `s<&'a str>` (lifetime mismatch) <anon>:9     s              ^ <anon>:8:47: 10:2 note: lifetime 'a defined on block @ 8:46... <anon>:8 fn test<'a>(s: s<&'a str>) -> s<&'static str> { <anon>:9     s <anon>:10 } note: ...does not outlive static lifetime 

if remove s , test_2, compiles fine, demonstrating function types indeed contravariant regard argument types.

i don't know what's happening , looks deserves question.


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -