首页 \ 问答 \ 避免结构中的PhantomData强制执行类型约束(Avoiding PhantomData in a struct to enforce type constraints)

避免结构中的PhantomData强制执行类型约束(Avoiding PhantomData in a struct to enforce type constraints)

我正在尝试开发一种批处理系统。 在那里我想使用某种Process结构,它拥有所有与流程相关的部分。 当前的实现使用PhantomData来强制执行类型约束:

pub struct Process<P: Producer<U>, T: Transformer<U, V>, C: Consumer<V>, U,V> 
{
    producer: P,
    transformer: T, 
    consumer: C,
    p1: PhantomData<U>,
    p2: PhantomData<V>,
}

这个想法是由Producer发出的类型将被Transformer (可能是另一种类型)使用,并由Consumer 。 因此类型必须匹配。

Process结构应该拥有实现ProducerTransformerConsumer特性的项目。 我想这就是为什么我需要使用类型参数。 因为我不能直接使用这个特质

...
producer: Producer<U>,
...

因为编译时未知的大小。

有没有更好的方法来做到这一点? 我对Rust很新,所以我可能会在错误的方向思考。

该解决方案有效,但对于那些PhantomData字段看起来有点奇怪。 也许这只是PhantomData的用途?


I'm trying to develop a kind of batch system. Within that I'd like to use some kind of Process struct, which owns all process related parts. The current implementation uses PhantomData to enforce the type constraints:

pub struct Process<P: Producer<U>, T: Transformer<U, V>, C: Consumer<V>, U,V> 
{
    producer: P,
    transformer: T, 
    consumer: C,
    p1: PhantomData<U>,
    p2: PhantomData<V>,
}

The idea is that type emitted by the Producer will be used by the Transformer (maybe to a different type) and consumed by the Consumer. Therefore the types must match.

The Process struct should own the items implementing the Producer, Transformer and Consumer traits. I think that's why I need to use type parameters. Since I cannot use the the trait directly like

...
producer: Producer<U>,
...

because of the unknown size at compile time.

Is there a better way of doing this? I'm pretty new to Rust, so I might be thinking in the wrong direction.

The solution works, but it looks a bit odd with those PhantomData fields. Maybe that is just what PhantomData is used for?


原文:https://stackoverflow.com/questions/33409546
更新时间:2022-04-01 10:04

最满意答案

我在片段的onCreateView中调用了SetValues方法。 最后我解决了这个问题

主要活动

public class CameraDetails extends Activity {
    private CameraData camera = new CameraData();

    Fragment network = new NetworkFragment();
    Fragment remoteUser = new RemoteUserFragment();
    Fragment rtsp = new RTSPFragmentTab();
    Fragment video = new VideoFragmentTab();
    Fragment record = new RecordFragmentTab();
    Fragment alarm = new AlarmFragmentTab();
    Fragment productinfo = new ProductInfoFragmentTab();

    private G.Interface mNetworkInterface = null;
    private G.Interface mRemoteUserInterface = null;    

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cameradetails);

        initCameraData();

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // network tab
        ActionBar.Tab tab = actionBar.newTab();
        tab.setText("Network");
        tab.setIcon(R.drawable.ic_launcher);
        tab.setTabListener(new TabListener(network));
        actionBar.addTab(tab);

        // remote user tab
        tab = actionBar.newTab();
        tab.setText("Remote User");
        tab.setIcon(R.drawable.ic_launcher);
        tab.setTabListener(new TabListener(remoteUser));
        actionBar.addTab(tab);        
    }

    public void initCameraData(){
        try{
            byte[] by = new byte[512];
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            File file = new File(extStorageDirectory, "dump.hex");
            BufferedInputStream in = new BufferedInputStream( new FileInputStream(file));
            in.read(by);
            in.close();
            camera.set( by );           
        } catch(Exception e){
            e.printStackTrace();
        }

    }

    public void onClick(View v){
        getActionBar().setSelectedNavigationItem(0);
        if(!mNetworkInterface.Validate())
            return;

        getActionBar().setSelectedNavigationItem(1);
        if(!mRemoteUserInterface.Validate())
            return;

        try{
            byte[] bytes = camera.get();
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            File file = new File(extStorageDirectory, "dump.hex");
            BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(file, false));
            out.write(bytes);
            out.close();
            Log.v("Data", "Setup data updated");
        } catch (Exception e) {
            e.printStackTrace();
            return ;
        }
    }

    public CameraData getCameraData(){
        return camera;
    }

    public void setNetworkListener( G.Interface Interface ){
        this.mNetworkInterface = Interface;
    }

    public void setRemoteUserListener( G.Interface Interface ){
        this.mRemoteUserInterface = Interface;
    }

}

网络碎片

public class NetworkFragment extends Fragment implements G.Interface {
    View rootView;
    Activity mActivity;
    CameraData camera;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.network_layout, container, false);
        Log.i("NetworkFragment", "CreateView");
        SetValues();
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        mActivity = activity;
        ((CameraDetails)mActivity).setNetworkListener(this);
        camera = ((CameraDetails)mActivity).getCameraData();
        Log.i("NetworkFragment", "Activity Attached");
        super.onAttach(activity);
    }

    @Override
    public boolean Validate() {
        try {
            String s;
            int i;

            // ip address
            camera.mNetwork.IPAddress = G.GetIPText(rootView, R.id.cd_ip_address);
            if( camera.mNetwork.IPAddress.isEmpty()){
                Toast.makeText(mActivity, "Please enter a valid ip address", Toast.LENGTH_SHORT).show();
                return false;
            }

            // subnet mask
            camera.mNetwork.SubnetMask = G.GetIPText(rootView, R.id.cd_subnetmask);
            if( camera.mNetwork.SubnetMask.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid subnetmask", Toast.LENGTH_SHORT).show();
                return false;
            }


            // gateway
            camera.mNetwork.Gateway = G.GetIPText(rootView, R.id.cd_gateway);
            if( camera.mNetwork.Gateway.isEmpty()){
                Toast.makeText(mActivity, "Please enter a valid gateway", Toast.LENGTH_SHORT).show();
                return false;
            }

            // com port
            camera.mNetwork.CommPort = G.GetInteger(rootView, R.id.cd_comm_port);
            if( camera.mNetwork.CommPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid Communication Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // mimg port
            camera.mNetwork.MImgPort = G.GetInteger(rootView, R.id.cd_mimg_port);
            if( camera.mNetwork.MImgPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid MIMG Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // webserver port
            camera.mNetwork.WebServerPort = G.GetInteger(rootView, R.id.cd_web_server_port);
            if( camera.mNetwork.WebServerPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid webserver Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi id
            camera.mNetwork.WiFiId = G.GetText(rootView, R.id.cd_wifi_id);
            if( camera.mNetwork.WiFiId.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid WiFi Id", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi password
            camera.mNetwork.WiFiPassword = G.GetText(rootView, R.id.cd_wifi_pwd);
            if( camera.mNetwork.WiFiPassword.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid WiFi Password", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi mode
            camera.mNetwork.WiFiMode = (byte)G.GetSpinnerOptions(rootView, R.id.cd_wifi_mode);
            if( camera.mNetwork.WiFiMode == -1 ){
                Toast.makeText(mActivity, "Please select a valid wifi mode from list", Toast.LENGTH_SHORT).show();
                return false;
            }

            Log.i("NetworkFragment", "Validation OK");
        } catch( Exception e ){
            e.printStackTrace();
        }
        return true;
    }

    public void SetValues() {
        try {
            // ip address
            EditText et = (EditText)rootView.findViewById(R.id.cd_ip_address);
            et.setText(camera.mNetwork.IPAddress);

            // subnet mask
            et = (EditText)rootView.findViewById(R.id.cd_subnetmask);
            et.setText(camera.mNetwork.SubnetMask);

            // gateway
            et = (EditText)rootView.findViewById(R.id.cd_gateway);
            et.setText(camera.mNetwork.Gateway);

            // com port
            et = (EditText)rootView.findViewById(R.id.cd_comm_port);
            et.setText(""+camera.mNetwork.CommPort);

            // mimg port
            et = (EditText)rootView.findViewById(R.id.cd_mimg_port);
            et.setText(""+camera.mNetwork.MImgPort);

            // webserver port
            et = (EditText)rootView.findViewById(R.id.cd_web_server_port);
            et.setText(""+camera.mNetwork.WebServerPort);

            // wifi id
            et = (EditText)rootView.findViewById(R.id.cd_wifi_id);
            et.setText(camera.mNetwork.WiFiId);

            // wifi password
            et = (EditText)rootView.findViewById(R.id.cd_wifi_pwd);
            et.setText(camera.mNetwork.WiFiPassword);

            // wifi mode
            Spinner sp = (Spinner)rootView.findViewById(R.id.cd_wifi_mode);
            sp.setSelection(camera.mNetwork.WiFiMode, true);


            Log.i("NetworkFragment", "SetValues OK");

        } catch( Exception e ){
            e.printStackTrace();
        }
    }

}

无论如何,感谢@ cricket_007帮助我理解片段标签操作


I called SetValues method in onCreateView of the fragment. Finally i solved the problem

Main Activity

public class CameraDetails extends Activity {
    private CameraData camera = new CameraData();

    Fragment network = new NetworkFragment();
    Fragment remoteUser = new RemoteUserFragment();
    Fragment rtsp = new RTSPFragmentTab();
    Fragment video = new VideoFragmentTab();
    Fragment record = new RecordFragmentTab();
    Fragment alarm = new AlarmFragmentTab();
    Fragment productinfo = new ProductInfoFragmentTab();

    private G.Interface mNetworkInterface = null;
    private G.Interface mRemoteUserInterface = null;    

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cameradetails);

        initCameraData();

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // network tab
        ActionBar.Tab tab = actionBar.newTab();
        tab.setText("Network");
        tab.setIcon(R.drawable.ic_launcher);
        tab.setTabListener(new TabListener(network));
        actionBar.addTab(tab);

        // remote user tab
        tab = actionBar.newTab();
        tab.setText("Remote User");
        tab.setIcon(R.drawable.ic_launcher);
        tab.setTabListener(new TabListener(remoteUser));
        actionBar.addTab(tab);        
    }

    public void initCameraData(){
        try{
            byte[] by = new byte[512];
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            File file = new File(extStorageDirectory, "dump.hex");
            BufferedInputStream in = new BufferedInputStream( new FileInputStream(file));
            in.read(by);
            in.close();
            camera.set( by );           
        } catch(Exception e){
            e.printStackTrace();
        }

    }

    public void onClick(View v){
        getActionBar().setSelectedNavigationItem(0);
        if(!mNetworkInterface.Validate())
            return;

        getActionBar().setSelectedNavigationItem(1);
        if(!mRemoteUserInterface.Validate())
            return;

        try{
            byte[] bytes = camera.get();
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            File file = new File(extStorageDirectory, "dump.hex");
            BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(file, false));
            out.write(bytes);
            out.close();
            Log.v("Data", "Setup data updated");
        } catch (Exception e) {
            e.printStackTrace();
            return ;
        }
    }

    public CameraData getCameraData(){
        return camera;
    }

    public void setNetworkListener( G.Interface Interface ){
        this.mNetworkInterface = Interface;
    }

    public void setRemoteUserListener( G.Interface Interface ){
        this.mRemoteUserInterface = Interface;
    }

}

Network Fragment

public class NetworkFragment extends Fragment implements G.Interface {
    View rootView;
    Activity mActivity;
    CameraData camera;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.network_layout, container, false);
        Log.i("NetworkFragment", "CreateView");
        SetValues();
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        mActivity = activity;
        ((CameraDetails)mActivity).setNetworkListener(this);
        camera = ((CameraDetails)mActivity).getCameraData();
        Log.i("NetworkFragment", "Activity Attached");
        super.onAttach(activity);
    }

    @Override
    public boolean Validate() {
        try {
            String s;
            int i;

            // ip address
            camera.mNetwork.IPAddress = G.GetIPText(rootView, R.id.cd_ip_address);
            if( camera.mNetwork.IPAddress.isEmpty()){
                Toast.makeText(mActivity, "Please enter a valid ip address", Toast.LENGTH_SHORT).show();
                return false;
            }

            // subnet mask
            camera.mNetwork.SubnetMask = G.GetIPText(rootView, R.id.cd_subnetmask);
            if( camera.mNetwork.SubnetMask.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid subnetmask", Toast.LENGTH_SHORT).show();
                return false;
            }


            // gateway
            camera.mNetwork.Gateway = G.GetIPText(rootView, R.id.cd_gateway);
            if( camera.mNetwork.Gateway.isEmpty()){
                Toast.makeText(mActivity, "Please enter a valid gateway", Toast.LENGTH_SHORT).show();
                return false;
            }

            // com port
            camera.mNetwork.CommPort = G.GetInteger(rootView, R.id.cd_comm_port);
            if( camera.mNetwork.CommPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid Communication Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // mimg port
            camera.mNetwork.MImgPort = G.GetInteger(rootView, R.id.cd_mimg_port);
            if( camera.mNetwork.MImgPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid MIMG Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // webserver port
            camera.mNetwork.WebServerPort = G.GetInteger(rootView, R.id.cd_web_server_port);
            if( camera.mNetwork.WebServerPort < 0 ){
                Toast.makeText(mActivity, "Please enter a valid webserver Port", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi id
            camera.mNetwork.WiFiId = G.GetText(rootView, R.id.cd_wifi_id);
            if( camera.mNetwork.WiFiId.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid WiFi Id", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi password
            camera.mNetwork.WiFiPassword = G.GetText(rootView, R.id.cd_wifi_pwd);
            if( camera.mNetwork.WiFiPassword.isEmpty() ){
                Toast.makeText(mActivity, "Please enter a valid WiFi Password", Toast.LENGTH_SHORT).show();
                return false;
            }

            // wifi mode
            camera.mNetwork.WiFiMode = (byte)G.GetSpinnerOptions(rootView, R.id.cd_wifi_mode);
            if( camera.mNetwork.WiFiMode == -1 ){
                Toast.makeText(mActivity, "Please select a valid wifi mode from list", Toast.LENGTH_SHORT).show();
                return false;
            }

            Log.i("NetworkFragment", "Validation OK");
        } catch( Exception e ){
            e.printStackTrace();
        }
        return true;
    }

    public void SetValues() {
        try {
            // ip address
            EditText et = (EditText)rootView.findViewById(R.id.cd_ip_address);
            et.setText(camera.mNetwork.IPAddress);

            // subnet mask
            et = (EditText)rootView.findViewById(R.id.cd_subnetmask);
            et.setText(camera.mNetwork.SubnetMask);

            // gateway
            et = (EditText)rootView.findViewById(R.id.cd_gateway);
            et.setText(camera.mNetwork.Gateway);

            // com port
            et = (EditText)rootView.findViewById(R.id.cd_comm_port);
            et.setText(""+camera.mNetwork.CommPort);

            // mimg port
            et = (EditText)rootView.findViewById(R.id.cd_mimg_port);
            et.setText(""+camera.mNetwork.MImgPort);

            // webserver port
            et = (EditText)rootView.findViewById(R.id.cd_web_server_port);
            et.setText(""+camera.mNetwork.WebServerPort);

            // wifi id
            et = (EditText)rootView.findViewById(R.id.cd_wifi_id);
            et.setText(camera.mNetwork.WiFiId);

            // wifi password
            et = (EditText)rootView.findViewById(R.id.cd_wifi_pwd);
            et.setText(camera.mNetwork.WiFiPassword);

            // wifi mode
            Spinner sp = (Spinner)rootView.findViewById(R.id.cd_wifi_mode);
            sp.setSelection(camera.mNetwork.WiFiMode, true);


            Log.i("NetworkFragment", "SetValues OK");

        } catch( Exception e ){
            e.printStackTrace();
        }
    }

}

Anyway thanks @cricket_007 for helping me to understand the fragment tab operation

相关问答

更多

相关文章

更多

最新问答

更多
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • linux的常用命令干什么用的
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • Java中的不可变类(Immutable class in Java)
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • 绑定属性设置器未被调用(Bound Property Setter not getting Called)
  • linux ubuntu14.04版没有那个文件或目录
  • 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
  • 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
  • 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
  • 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
  • 如何按部门显示报告(How to display a report by Department wise)
  • Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
  • Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
  • WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)