Usage of '...' (Three-Dots or Dot-Dot-Dot) in Functions

Usage of `...` (three-dots or dot-dot-dot) in functions

The word used to describe ... is "ellipsis." Knowing this should make searching for information about the construct easier. For example, the first hit on Google is another question on this site: How to use R's ellipsis feature when writing your own function?

Question about a function definition (three dots in parameters..)

These type of functions are called variadic functions (Wikipedia link). They use ellipses (i.e., three dots) to indicate that there is a variable number of arguments that the function can process. One place you've probably used such functions (perhaps without realising) is with the various printf functions, for example (from the ISO standard):

int printf(const char * restrict format, ...);

The ellipses allow you to create functions where the number of parameters are not known beforehand, and you can use stdargs.h functions (va_start, va_arg and va_end) to get the specific arguments.

You do have to know the types of the arguments you extract and have some way of deciding when you're done. The printf functions do this with the format string (for both types and count), while my example code below always assumes const char * as the type with a sentinel value NULL to decide completion.

This link here has a good treatise on the use of variable argument lists in printf.


As an example, the following program contains a function outStrings(), that allows you to print an arbitrary number of strings:

#include <stdio.h>
#include <stdarg.h>

void outStrings(const char *strFirst, ...) {
// First argument handled specially.

printf("%s", strFirst);
va_list pArg;
va_start(pArg, strFirst);

// Just get and process each string until NULL given.

const char *strNext = va_arg(pArg, const char *);
while (strNext != NULL) {
printf("%s", strNext);
strNext = va_arg(pArg, const char *);
}

// Finalise processing.

va_end(pArg);
}

int main(void) {
char *name = "paxdiablo";
outStrings("Hello, ", name, ", I hope you're feeling well today.\n", NULL);
}

What is the meaning of foo(...arg) (three dots in a function call)?

This has nothing to do with jQuery or Angular. It's a feature that was introduced in ES2015.

This particular use of ... doesn't actually have an official name. A name that is in line with other uses would be "spread argument" (a generic term would be "spread syntax"). It "explodes" (spreads) an iterable and passes each value as argument to the function. Your example is equivalent to:

this.heroes.push.apply(this.heroes, Array.from(heroes));

Besides being more concise, another advantage of ... here is that it can be more easily used with other concrete arguments:

func(first, second, ...theRest);

// as opposed to the following or something similar:
func.apply(null, [first, second].concat(Array.from(heroes)));

What is the meaning of three dots (...) in PHP?

This is literally called the ... operator in PHP, but is known as the splat operator from other languages. From a 2014 LornaJane blog post on the feature:

This feature allows you to capture a variable number of arguments to a function, combined with "normal" arguments passed in if you like. It's easiest to see with an example:

function concatenate($transform, ...$strings) {
$string = '';
foreach($strings as $piece) {
$string .= $piece;
}
return($transform($string)); }

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");

(This would print I'D LIKE 6 APPLES)

The parameters list in the function declaration has the ... operator in it, and it basically means " ... and everything else should go into $strings". You can pass 2 or more arguments into this function and the second and subsequent ones will be added to the $strings array, ready to be used.

What do 3 dots next to a parameter type mean in Java?

It means that zero or more String objects (or a single array of them) may be passed as the argument(s) for that method.

See the "Arbitrary Number of Arguments" section here: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

In your example, you could call it as any of the following:

myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});

Important Note: The argument(s) passed in this way is always an array - even if there's just one. Make sure you treat it that way in the method body.

Important Note 2: The argument that gets the ... must be the last in the method signature. So, myMethod(int i, String... strings) is okay, but myMethod(String... strings, int i) is not okay.

Thanks to Vash for the clarifications in his comment.

Pass optional arguments to function, three dots

Because everything you pass in the ... stays in the .... Variables you pass that aren't explicitly captured by a parameter are not expanded into the local environment. The ... should be used for values your current function doesn't need to interact with at all, but some later function does need to use do they can be easily passed along inside the .... It's meant for a scenario like

ss <- function(x) {
x
}

tt <- function(...) {
return(ss(...))
}

tt(x=2)

If your function needs the variable x to be defined, it should be a parameter

tt <- function(x, ...) {
return(x)
}

If you really want to expand the dots into the current environment (and I strongly suggest that you do not), you can do something like

tt <- function(...) {
list2env(list(...), environment())
return(x)
}

Function with three dots argument

A function with three dots means, that you can pass a variable number of arguments. Since the called function doesn't really know how many arguments were passed, you usually need some way to tell this. So some extra parameter would be needed which you can use to determine the arguments.

A good example would be printf. You can pass any number of arguments, and the first argument is a string, which describes the extra parameters being passed in.

void func(int count, ...)
{
va_list args;
int i;
int sum = 0;

va_start(args, count);
for(i = 0; i < count; i++)
sum += va_arg(args, int);
va_end(ap);

printf("%d\n", sum);
}

update

To address your comment, you don't need the names of the arguments. That is the whole point of it, because you don't know at compile time which and how many arguments you will pass. That depends on the function of course. In my above example, I was assuming that only ints are passed though. As you know from printf, you pass any type, and you have to interpret them. that is the reason why you need a format specifier that tells the function what kind of parameter is passed. Or as shown in my example you can of course assume a specific type and use that.

What do the three dots before a function argument represent?

It indicates that there may be a variable number of arguments.

When the function is called with more than 3 arguments, all the arguments after $next will be added to the $guards array.

You can read about it here.

What are these three dots in React doing?

That's property spread notation. It was added in ES2018 (spread for arrays/iterables was earlier, ES2015), but it's been supported in React projects for a long time via transpilation (as "JSX spread attributes" even though you could do it elsewhere, too, not just attributes).

{...this.props} spreads out the "own" enumerable properties in props as discrete properties on the Modal element you're creating. For instance, if this.props contained a: 1 and b: 2, then

<Modal {...this.props} title='Modal heading' animation={false}>

would be the same as

<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

But it's dynamic, so whatever "own" properties are in props are included.

Since children is an "own" property in props, spread will include it. So if the component where this appears had child elements, they'll be passed on to Modal. Putting child elements between the opening tag and closing tags is just syntactic sugar — the good kind — for putting a children property in the opening tag. Example:

class Example extends React.Component {  render() {    const { className, children } = this.props;    return (      <div className={className}>      {children}      </div>    );  }}ReactDOM.render(  [    <Example className="first">      <span>Child in first</span>    </Example>,    <Example className="second" children={<span>Child in second</span>} />  ],  document.getElementById("root"));
.first {  color: green;}.second {  color: blue;}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


Related Topics



Leave a reply



Submit