带有options参数的函数的绑定

时间:2018-01-13 11:02:25

标签: reason bucklescript

在JavaScript中通常的做法是使用一个带有options参数的函数,如下所示:

function foo({ bar1, bar2, bar3 }) {}
foo({ bar1: 5, bar2: 3 })

在Reason / OCaml中,人们更愿意为这些函数使用带标签的参数:

let foo = (~bar1, ~bar2, ~bar) => {}
foo(~bar1=5, ~bar2=3, ())

现在,我知道有这种方法可以为这些函数创建Reason / Bucklescript绑定:

type barObj;
[@bs.obj] external makeBarObj : (
  ~bar1: int=?,
  ~bar2: int=?,
  ~bar3: int=?,
  unit
) => barObj = "";

external foo : barObj => t = "foo";

foo(makeBarObj(~bar1=5, ~bar2=3, ());

但是,是否有更简单的方法为这些函数编写绑定?我对这种方法的问题是,当调用一个接受一个options对象的函数时,它变得非常“长”,特别是如果它是一个多态参数,例如:

foo(`BarObj(makebarObj(~bar1=5, ~bar2=3, ())));

2 个答案:

答案 0 :(得分:3)

您可以直接构造对象,而不是使用单独的函数:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Home - Motive Media Productions</title>
        <link rel="stylesheet" href="style.css">
        <link href="https://fonts.googleapis.com/css?family=Oswald:500,600,700" rel="stylesheet">
    </head>
    <body>
        <div class="section1">
            <div id="overlay">
                <h1>Text</h1>
            </div>
        </div>
    </body>
    <footer>
        <div class="copyright">
            <p>&copy; 2018</p>
        </div>
        <div class="brands">
            <div class="social-media">
                    <a href="http://www.facebook.com/" target="_blank">
                        <img src="files/facebook.png"></a>
                    <a href="http://www.instagram.com/" target="_blank">
                        <img src="files/instagram.png"></a>
                    <a href="http://www.twitter.com/" target="_blank">
                        <img src="files/twitter.png"></a>
            </div>
        </div>
        <div class="contact">
            <li class="contact-list">
                <a href="00">00</a>
            </li>
            <li class="contact-list">
                <a href="mailto:hi@hi.com">hi@hi.com</a>
            </li>
        </div>
    </footer>
</html>

只需

即可调用
[@bs.val] external foo : Js.t({..}) => t = "";
let foo = (~bar1=?, ~bar2=?, ~bar3=?, unit) =>
  foo({
    "bar1": Js.Nullable.from_opt(bar1),
    "bar2": Js.Nullable.from_opt(bar2),
    "bar3": Js.Nullable.from_opt(bar3)
  });

但请注意,这并不完全等同foo(~bar1=5, ~bar2=3, ()); 生成的内容,因为[@bs.obj]属性并不总是被解释为未定义。

如果你需要将它包装在变量中,你可以将对象构造函数包装起来。您通常也可以定义一组函数:

undefined

答案 1 :(得分:1)

另一个假设似乎是这个:

[@bs.obj]
external makeBarObj : (~bar1: string=?, ~bar2: int=?, ~bar3: string=?, unit) => barObj =
  "";

[@bs.val] external foo : barObj => t = "foo";

let foo = (~bar1=?, ~bar2=?, ~bar3=?) => foo(makeBarObj(~bar1?, ~bar2?, ~bar3?, ()));

然后这样,API的客户端可以简单地调用:

foo(~bar1=5, ~bar2=3, ())

它与问题中提供的解决方案基本相同,但这会隐藏库中的对象转换代码,以便客户端不必担心它。