在 Mathematica 中安全地设置“结构”

2023-11-22

像 Mathematica 中那样进行记录的问题已经在几个地方讨论过,例如Mathematica 中的结构数据类型?.

所有这些方法的问题在于,人们似乎失去了执行以下操作的能力: 对每个参数进行特定的额外检查,就像当一个参数这样做时x_?NumericQ.

我的问题是:Mathematica 中有没有一种方法可以创建记录或结构,同时能够对各个元素使用上面的检查?

我正在尝试确定一种使用方法,因为我厌倦了使用 10 个参数调用函数(有时无法避免这一点),即使我尝试使每个函数非常具体,以最大限度地减少参数,有些函数只需要很多参数来完成特定的工作。

首先我展示一下我所知道的三种方法。

Method 1

foo[p_]:=Module[{},
    Plot[Sin[x],{x,from/.p,to/.p}]
]
p={from->-Pi,to->Pi};
foo[p]

优点:安全,就像我将符号“from”更改为其他内容一样,它仍然可以工作。正如下面的例子。

foo[p_]:=Module[{},
    Plot[Sin[x],{x,from/.p,to/.p}]
]
p={from->-Pi,to->Pi};
from=-1; (* By accident the symbol from was set somewhere. It will work*)
foo[p]

Method 2

Clear[p,foo];
foo[p_]:=Module[{},
    Print[p];
    Plot[Sin[x],{x,p["from"],p["to"]}]
]
p["from"] = -Pi;
p["to"]   = Pi;

foo[p]

优点:也安全,字符串是不可变的。不必担心“from”值发生变化。但是到处都有字符串不是太可读了吗?

Method 3

Clear[p,to,from];
foo[p_]:=Module[{},
    Plot[Sin[x],{x,p[from],p[to]}]
]
p[from] = -Pi;
p[to]   = Pi;

foo[p]

缺点:如果任何符号“from”或“to”在某处被覆盖,将会导致问题,如

from=-4; (*accidentally the symbol from is assigned a value*)
foo[p]   

所以。我认为方法(1)是最安全的。但现在我失去了这样做的能力:

foo[from_?NumericQ, to_?NumericQ] := Module[{},
    Plot[Sin[x], {x, from, to}]
]
from = -Pi; to = Pi;
foo[from, to]

所以,我希望得到一个想法,能够将“记录”结合起来,但同时仍然能够对记录中的各个元素使用参数检查?或者这个问题对于 Mathematica 基于函数/规则的编程风格来说不是很好吗?

这是我希望 Mathematica 拥有的一件事,它是一个真实的记录,可以帮助管理和组织程序中使用的所有变量。


首先,我想提一下,您列出的所有方法在我看来都是有缺陷且危险的。我不喜欢它们的主要原因是它们引入了对全局变量的隐式依赖(讨论了这种情况不好的原因,例如here),并且还可能扰乱范围。它们的另一个问题是,这些方法看起来不能很好地扩展到同时存在的结构的许多实例。您列出的第二种方法似乎是最安全的,但它也有其问题(字符串作为字段名称,无法对此类结构进行类型检查,而且那里使用的符号也可能意外具有值)。

在我的帖子中here我讨论了一种构建可变数据结构的可能方法,其中方法可以进行额外的检查。我将相关部分复制到这里:

Unprotect[pair, setFirst, getFirst, setSecond, getSecond, new, delete];
ClearAll[pair, setFirst, getFirst, setSecond, getSecond, new, delete];
Module[{first, second},
   first[_] := {};
   second[_] := {};
   pair /: new[pair[]] := pair[Unique[]];
   pair /: new[pair[],fst_?NumericQ,sec_?NumericQ]:= 
      With[{p=new[pair[]]}, 
          p.setFirst[fst];
          p.setSecond[sec];
          p];
   pair /: pair[tag_].delete[] := (first[tag] =.; second[tag] =.);
   pair /: pair[tag_].setFirst[value_?NumericQ] := first[tag] = value;
   pair /: pair[tag_].getFirst[] := first[tag];
   pair /: pair[tag_].setSecond[value_?NumericQ] := second[tag] = value;
   pair /: pair[tag_].getSecond[] := second[tag];       
];
Protect[pair, setFirst, getFirst, setSecond, getSecond, new, delete]; 

请注意,我在构造函数和设置器中添加了检查,以说明如何完成此操作。有关如何使用以这种方式构建的结构的更多详细信息,您可以在我提到的帖子以及那里找到的更多链接中找到。

您的示例现在将显示为:

foo[from_?NumericQ, to_?NumericQ] :=
   Module[{}, Plot[Sin[x], {x, from, to}]];
foo[p_pair] := foo[p.getFirst[], p.getSecond[]]
pp = new[pair[], -Pi, Pi];
foo[pp]

请注意,这种方法的主要优点是状态被正确封装,实现细节被隐藏,并且范围界定不会面临危险。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Mathematica 中安全地设置“结构” 的相关文章

随机推荐

  • PHP 中可以有嵌套类吗?

    我不是在谈论继承 我不是在谈论嵌套对象 我在说话 System Web Templating 一种筑巢 这些是您不应该创建实例的类 所以 No 但是 您可以通过在 getInstance 中返回实例化对象来执行类似的操作 myClass g
  • 谷歌地图使用 PHP 在 MySQL 中保存多边形和点

    现在我有一个应用程序 允许用户在谷歌地图上绘制多边形 我需要使用 PHP 和 MySQL 保存这个多边形 但我不确定最佳实践 我应该启用空间扩展并保存几何图形吗 我应该将每个垂直 纬度 经度对 保存在数组中吗 我不知道的另一种方法 我想知道
  • Internet Explorer 中触发 window.resize 事件

    如您所知 在 Internet Explorer 中 当页面上的任何元素调整大小时 将触发 window resize 事件 页面元素是否通过分配 更改其高度或样式属性 通过简单地向其添加子元素或其他方式来调整页面元素的大小并不重要 即使元
  • C# 数据集访问数据库

    我有一个从 csv 文件动态创建的数据集 我想要做的是将行插入到我的 MS Access 表中 但我不知道从哪里开始 数据集中数据的标头可能会因顺序而异 但标头的名称将始终与 Access 数据库匹配 我是否必须在插入命令中静态调用标头名称
  • WPF 将用户控件属性绑定到父属性

    我创建了一个用户控件 它有 2 个依赖属性 我想将这些依赖属性绑定到 mainViewModel 的属性 以便每当用户控件中的某些内容发生更改时 父级的属性都会更新 我尝试过 可以正常绑定 但没有成功 如何将用户控件的 DP 绑定到父级的属
  • javascript中的第n个孩子

    这是我的 jquery 代码 我需要 javascript 代码来选择第 n 个孩子 是否可以使用 javascript 选择第 n 个孩子
  • 如何剪辑或剪切可组合项?

    如何剪辑或剪切可组合内容以使图像 按钮或可组合项具有自定义形状 这个问题不是关于使用Modifier clip 更像是用替代方法来完成任务 这些方法允许产生不可能的结果 或者当很难创建像云或方圆这样的形状时 This is 分享您的知识 问
  • 如何显示 HTML 资源文件?

    我有一个 html文件在我的assets目录 如何在 Flutter 中显示 渲染它 包裹来自颤动团队昨天发布 webview flutter 如何加载本地资源 将文件添加到项目并更新您的 pubspec assets assets you
  • 在 jQuery 中设置日期格式

    var date Fri Jan 29 2012 06 12 00 GMT 0100 我怎样才能以格式显示它2012 01 29 06 12 在 PHP 中是函数 gt 格式 在 Javascript 中也是格式 但如果我尝试使用它 则会出
  • 使用 useEffect 和异步函数反应错误边界,我缺少什么?

    In my Hello jsx我正在调用一个可能会失败的 API 组件 这里调用了一个假APIloader import React useEffect from react export const Hello gt const load
  • 是否可以更改 docker 容器中的日期?

    我有一个容器 里面有一个正在运行的程序 tomcat 我只需要更改此容器中的日期并测试我的程序行为 我有时间敏感的逻辑 有时需要看看几天或几个月后会发生什么 在docker中可以吗 我读到 如果我更改容器中的日期 主机系统上的日期也会更改
  • 为 Firebase 部署单独的 Cloud Function

    我希望能够为 Firebase 部署单独的 Cloud Function 这样我就不必每次都部署整个项目 没有通过 CLI 的选项 但如果 Google 或 Firebase 公开了一个 REST API 或其他一些接口来简化此操作 那就太
  • 如何将表情符号与 R 正则表达式匹配?

    我想确定矢量的哪些元素包含表情符号 x c no no x 1 U0001f602 no U0001f379 U0001f600 no U0001f61b 相关文章仅涵盖其他语言 并且因为它们大多引用专门的库 所以我无法找到翻译为 R 的方
  • 使用大量控件填充 FlowLayoutPanel 并按需绘制缩略图

    我正在尝试做一个ImageListBox一种可以显示大量缩略图的控件 就像 Picasa 使用的控件一样 这是我的设计 我有一个FlowLayoutPanel那里居住着很多UserControl对象 例如 4 000 个 每个UserCon
  • log-sum-exp 技巧为什么不递归

    我一直在研究 log sum exp 问题 我有一个以对数形式存储的数字列表 我想将其求和并以对数形式存储 朴素的算法是 def naive listOfLogs return math log10 sum 10 x for x in li
  • 作为开发人员,不同的 Ruby 线程模型(Ruby 与 JRuby)会对您的代码产生什么实际影响?

    我试图了解 MRI Ruby 1 8 和 JRuby 之间不同线程模型的实际影响 作为开发人员 这种差异对我意味着什么 另外 MRI Ruby 1 8 中是否有任何实际代码示例 由于不同的线程模型 它们在 JRuby 上的性能特征会更差 S
  • 如何进入微软的.NET框架源代码?

    我想进入微软的源代码 但不能 我按照以下说明进行操作配置 Visual Studio 进行调试 特别是 我禁用了 仅启用我的代码 并启用了 启用 NET Framework 源步进 最后 将源符号位置设置为 http referenceso
  • nginx 作为 NodeJS+socket.io 的代理:除了大消息外一切正常

    正如上所解释的nginx 的网站我使用了 nginx 的这些设置来将 websocket 代理到 NodeJS 服务器 location socket io proxy pass http backend proxy http versio
  • 为什么Javascript ===/== 字符串相等有时具有恒定时间复杂度,有时具有线性时间复杂度?

    在我发现常见 最新的 Javascript 实现正在使用 String Interning 来提高性能之后 常见的 JavaScript 实现是否使用字符串驻留 我想 对于字符串将得到常数 O 1 时间 所以我对这个问题给出了错误的答案 J
  • 在 Mathematica 中安全地设置“结构”

    像 Mathematica 中那样进行记录的问题已经在几个地方讨论过 例如Mathematica 中的结构数据类型 所有这些方法的问题在于 人们似乎失去了执行以下操作的能力 对每个参数进行特定的额外检查 就像当一个参数这样做时x Numer