This is very simple program which clones structure of existing table into new empty table. It can clone partitioning too.

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/bigquery"
)

var (
	projectID     = "your_google_project"
	printDebugMsg = false
)

func main() {

	paramSourceDataset := flag.String("source_dataset", "", "BQ dataset name")
	paramSourceTable := flag.String("source_table", "", "BQ table name")
	paramTargetDataset := flag.String("target_dataset", "", "BQ dataset name")
	paramTargetTable := flag.String("target_table", "", "BQ table name")
	paramDebug := flag.Bool("debug", false, "print debug messages")
	paramHelp := flag.Bool("help", false, "print help")
	flag.Parse()

	printDebugMsg = *paramDebug
	printHelpMsg := *paramHelp
	bqSourceDataset := *paramSourceDataset
	bqSourceTable := *paramSourceTable
	bqTargetDataset := *paramTargetDataset
	bqTargetTable := *paramTargetTable
	debugMsg(fmt.Sprintf("printDebugMsg: %v", printDebugMsg))
	debugMsg(fmt.Sprintf("printHelpMsg: %v", printHelpMsg))
	debugMsg(fmt.Sprintf("bqSourceDataset: %v", bqSourceDataset))
	debugMsg(fmt.Sprintf("bqSourceTable: %v", bqSourceTable))
	debugMsg(fmt.Sprintf("bqTargetDataset: %v", bqTargetDataset))
	debugMsg(fmt.Sprintf("bqTargetTable: %v", bqTargetTable))

	if bqSourceDataset == "" || bqSourceTable == "" {
		fmt.Println("you must specify source dataset and table name")
		printHelpMsg = true
	}

	if printHelpMsg == true {
		flag.PrintDefaults()
		log.Fatal()
	}

	ctx := context.Background()
	source, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		log.Fatalln("ERROR: Cannot open BQ client: ", err)
	}

	table := source.Dataset(bqSourceDataset).Table(bqSourceTable)

	tableMeta, err := table.Metadata(ctx)

	if err == nil {
		sch := tableMeta.Schema
		colCount := len(sch)
		printMsg("Reading structure of the table: ", bqSourceDataset, ".", bqSourceTable)
		printMsg("num of columns: ", colCount)
		bqschema := make(bigquery.Schema, colCount)
		for i := range sch {
			var colDetail bigquery.FieldSchema
			col := sch[i]
			printMsg(i, ": name: ", col.Name, ", type: ", col.Type, ", required: ", col.Required)
			colDetail.Name = col.Name
			colDetail.Type = col.Type
			colDetail.Required = col.Required
			bqschema[i] = &colDetail
		}

		printMsg("object type: ", tableMeta.Type)
		debugMsg("streaming buffer: ", tableMeta.StreamingBuffer)
		debugMsg("etag: ", tableMeta.ETag)

		if tableMeta.TimePartitioning != nil {
			printMsg("TimePartitioning.Expiration: ", tableMeta.TimePartitioning.Expiration)
		}

		if bqTargetDataset != "" && bqTargetTable != "" {

			target := source.Dataset(bqTargetDataset).Table(bqTargetTable)

			if tableMeta.TimePartitioning != nil {
				printMsg("creating partitioned table: ", bqTargetDataset, ".", bqTargetTable)
				var timepart bigquery.TimePartitioning
				timepart.Expiration = tableMeta.TimePartitioning.Expiration

				err = target.Create(ctx, bqschema, timepart)
			} else {
				printMsg("creating normal table: ", bqTargetDataset, ".", bqTargetTable)
				err = target.Create(ctx, bqschema)
			}

			if err != nil {
				log.Fatal("ERROR: cannot create target table: ", err)
			}
			printMsg("target table created")
		} else {
			printMsg("target table not specified")
		}
	} else {
		printMsg("ERROR in checking source table metadata: ", err)
	}
}

func curTime() string {
	return time.Now().UTC().Format(time.RFC3339) + ":"
}

func debugMsg(t ...interface{}) {
	if printDebugMsg == true {
		printMsg(t...)
	}
}

func printMsg(t ...interface{}) {
	fmt.Println(curTime(), fmt.Sprint(t...))
}