Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is ...interface{} as an argument

Tags:

go

I am referring to the source of func Printf on http://golang.org/pkg/log/

func Printf(format string, v ...interface{})
Printf calls Output to print to the standard logger. Arguments are handled in the manner of fmt.Printf.

I have two questions:

  1. What is the '...' ?
  2. What does ...interface{} mean?

Thank you very much

like image 990
samol Avatar asked Sep 05 '13 06:09

samol


1 Answers

This isn't exactly specific to go, so unlike the other answerers I'll go the more general route.

On Variable Arguments (...)

... here, called "ellipsis", indicates the function can receive a variable number of arguments, often referred to as varargs (or var-args, or other spellings). This is called a variadic function.

It simply means that, according to the following signature:

func Printf(format string, v ...interface{}) (n int, err error) {}

Printf will expect a first argument of type string, and then between 0 and N arguments of type interface{}. More on that type in the next section.

While the ability to supply any number of arguments can seem very handy, and without going into too much details here for risk of going off-topic, it comes with a few caveats depending on the implementation in the language:

  • increase in memory consumption,
  • decrease in readability,
  • decrease in code security.

I'll leave it up to you to look up why from the resources above.

On the Empty Interface (interface{})

This syntax bit is a bit more Go-specific, but the hint is in the name: interface.

An interface (or closer to Go's paradigm, a protocol), is a type that defines a contract for other objects to comply to. According to this Wikipedia article on interfaces in computing (emphasis in bold mine and corrections in italics mine):

In object-oriented languages, **the term "interface" is often used to define an abstract type that contains no data, but exposes behaviors defined as methods. A class having all the methods corresponding to that interface is said to implement that interface. Furthermore, a class can [in some languages]) implement multiple interfaces, and hence can be of different types at the same time.

An interface is hence a type definition; anywhere an object can be exchanged (in a function or method call) the type of the object to be exchanged can be defined in terms of an interface instead of a specific class. This allows later code to use the same function exchanging different object types; _[aiming to be]_ generic and reusable.

Now back to Go's Empty Interface

Go is a strongly typed language, with several built-in types, including Interface Types, which they describe as gollows in the current (1.1) language specifications:

An interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface.

Futher down, you are introduced to the construct you see in Printf's signature, interface{} (emphasis in bold mine):

A type implements any interface comprising any subset of its methods and may therefore implement several distinct interfaces. For instance, all types implement the empty interface:

interface{}

This basically means that any type an be represented as the "empty interface", and thus that Printf can accept variables of any type for these varargs.


A Quick Comparison with Other Languages

Historically, the name printf comes from the C function and from the binary of the same name, printf meaning "print formatted", though there were variadic print functions in earlier languages, and variadic functions are used for many other scenarios. However, printf is often considered the prime example of such a use. It's signature in C is:

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

As a result of their practicality, varargs and printf's familiar face show up in most languages...

In Java, printf exists under multiple forms, notably from the PrintStream class:

public PrintStream printf(String format, Object... args)

Some other langauges do not bother with specifying variable arguments and make it implicit, for instance in JavaScript, the arguments special variable within a function allows to access any arguments passed to a function, whether they match the prototype or not.

The console.log() method would be an example similar to printf, with the following pseudo-signature expanded for clarity (but actually simply using arguments):

console.log(obj1 [, obj2, ..., objN);
console.log(msg [, subst1, ..., substN);
like image 88
haylem Avatar answered Sep 18 '22 11:09

haylem